Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么这个输出看起来不确定?(是sprintf、printf还是十六进制文本的语法?) tl;博士_C++_Debugging_Printf_Hex - Fatal编程技术网

C++ 为什么这个输出看起来不确定?(是sprintf、printf还是十六进制文本的语法?) tl;博士

C++ 为什么这个输出看起来不确定?(是sprintf、printf还是十六进制文本的语法?) tl;博士,c++,debugging,printf,hex,C++,Debugging,Printf,Hex,为什么每次运行此代码()时都会得到不同的输出: 现在,我需要为这段代码编写一个(更简单的)变体: char login[21]; sprintf(login, "\x15\x00\x01%-8s%-10s", _user, _password); 不知怎的,这不管用!奇怪的是,后者每次都会产生不同的结果 思想 前一个示例的末尾只有一个十六进制文字。这是否掩盖了前者的问题 或者,我真的弄乱了我的调试输出,printf?(顺便说一下,我从中获得了&0xf

为什么每次运行此代码()时都会得到不同的输出:

现在,我需要为这段代码编写一个(更简单的)变体:

char login[21];
sprintf(login,
       "\x15\x00\x01%-8s%-10s",
       _user,
       _password);
不知怎的,这不管用!奇怪的是,后者每次都会产生不同的结果


思想
  • 前一个示例的末尾只有一个十六进制文字。这是否掩盖了前者的问题

  • 或者,我真的弄乱了我的调试输出,
    printf
    ?(顺便说一下,我从中获得了
    &0xff
    东西。)

  • 它是否与使用
    char
    而不是
    无符号char
    有关?但是,为什么前一个案例有效


  • 问题是字符串文本中嵌入了NUL字节,这就
    sprintf
    而言标记了字符串的结尾。因此,您的呼叫与以下内容相同:

    sprintf(login,
           "\x15",
           _user,
           _password);
    
    这只会将两个字节写入
    login
    数组:
    0x15 0x00

    有几种方法可以解决字节和字符的混合问题。我的选择大致如下:

    memcpy(login, "\x15\x00\x01", 3);
    sprintf(login + 3,
       "%-8s%-10s",
       _user,
       _password);    
    
    memcpy
    的调用将字节数作为参数,因此它不受嵌入式NUL问题的影响

    但是请注意,
    sprintf
    automaticall在输出字符串的末尾添加了一个NUL字节,因此实际上需要22个字节:3+8+10+1=22:

    char login[22];
    

    您的问题是,第二个格式字符串包含一个空字符(
    \x00
    ),它会提前终止该字符串。将字符串改为使用
    %c
    ,并在其中打印空字符。

    空字符
    “\x00”
    是否意味着格式字符串提前终止?(考虑到
    sprintf
    只理解以null结尾的字符串…)除了下面的答案之外:如果没有终止,您的
    登录名
    将太短,无法容纳所有内容->未定义的行为(“如果”是这种情况)。(好吧,现在答案中也有了)顺便说一句,你在第一个数组中超出了你的数组边界。线阵列的长度为38个字符,表示37+1(1为终止符,37为允许的最大长度)。您链接的示例输出是38个打印字节,这意味着您的sprintf正在写入39个,包括终止符,从而调用UB。除非我弄错了,
    sprintf
    不会自动以null终止,所以在我们的例子中,我们没有问题。该缓冲区直接馈送到网络句柄,我们还向其传递要发送的字节数,即21或38。(并不是说我认为这就是事情应该做的事情。我们甚至不使用
    bool
    ,因为它在我的公司成立时并不存在。)“sprintf”肯定会终止如果达到最大长度,snprintf'将不会null终止,这可能是令人困惑的地方?正是它。非常感谢。
    sprintf(login,
           "\x15",
           _user,
           _password);
    
    memcpy(login, "\x15\x00\x01", 3);
    sprintf(login + 3,
       "%-8s%-10s",
       _user,
       _password);    
    
    char login[22];