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];