打印存储为字符串的十六进制值会产生意外输出
Printing the hex value stored as a string gives unexpected output
我在字符串中定义了 C 语言的十六进制数字:
char chars[] = "\xfb\x54\x9c\xb2\x10\xef\x89\x51\x2f\x0b\xea\xbb\x1d\xaf\xad\xf8";
然后我想将这些值与另一个值进行比较。它不起作用,如果我打印如下值:
printf("%02x\n", chars[0]);
它写fffffffb
。为什么会这样以及如何准确获得 fb
值?
这是因为符号扩展。
改变
printf("%02x\n", chars[0]);
到
printf("%02x\n", (unsigned char)chars[0]);
%x
格式说明符在 32 位机器上将显示为 4 bytes
。由于你已经声明chars
为字符数组,当取值fb
(负值)时将被符号扩展为fffffffb
,其中fb
的MSB被设置为它之前的所有其他位。
更多详细信息请参阅此内容sign extension
如果您将 char chars[]
声明为 unsigned char chars[]
,那么打印结果会如预期的那样。
因为符号扩展。
这将如您所愿地工作:
printf("%02x\n", (unsigned char)chars[0]);
根据关于 %x
格式说明符的标准提及 fprintf()
o,u,x,X
The unsigned int argument is converted to unsigned octal (o), unsigned
decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; [...]
因此,%x
的预期参数类型是 unsigned int
。
现在,printf()
是一个可变参数函数,只有默认的提升规则适用于它的参数。在您的代码中,chars
是 char
类型的数组(其符号取决于实现),如果
printf("%02x\n", chars[0]);
chars[0]
的值被提升为 int
,这不是 %x
的预期类型。因此,输出是错误的,因为 int
和 unsigned int
不是同一类型。 [参考§6.7.2,C11
]。所以,没有像
这样的显式转换
printf("%02x\n", (unsigned int)chars[0]);
它调用 undefined behaviour.
FWIW,如果你有一个支持 C99 的编译器,你可以使用 hh
长度修饰符来解决这个问题,比如
printf("%02hhx\n", (unsigned char)chars[0]);
我在字符串中定义了 C 语言的十六进制数字:
char chars[] = "\xfb\x54\x9c\xb2\x10\xef\x89\x51\x2f\x0b\xea\xbb\x1d\xaf\xad\xf8";
然后我想将这些值与另一个值进行比较。它不起作用,如果我打印如下值:
printf("%02x\n", chars[0]);
它写fffffffb
。为什么会这样以及如何准确获得 fb
值?
这是因为符号扩展。
改变
printf("%02x\n", chars[0]);
到
printf("%02x\n", (unsigned char)chars[0]);
%x
格式说明符在 32 位机器上将显示为 4 bytes
。由于你已经声明chars
为字符数组,当取值fb
(负值)时将被符号扩展为fffffffb
,其中fb
的MSB被设置为它之前的所有其他位。
更多详细信息请参阅此内容sign extension
如果您将 char chars[]
声明为 unsigned char chars[]
,那么打印结果会如预期的那样。
因为符号扩展。
这将如您所愿地工作:
printf("%02x\n", (unsigned char)chars[0]);
根据关于 %x
格式说明符的标准提及 fprintf()
o,u,x,X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; [...]
因此,%x
的预期参数类型是 unsigned int
。
现在,printf()
是一个可变参数函数,只有默认的提升规则适用于它的参数。在您的代码中,chars
是 char
类型的数组(其符号取决于实现),如果
printf("%02x\n", chars[0]);
chars[0]
的值被提升为 int
,这不是 %x
的预期类型。因此,输出是错误的,因为 int
和 unsigned int
不是同一类型。 [参考§6.7.2,C11
]。所以,没有像
printf("%02x\n", (unsigned int)chars[0]);
它调用 undefined behaviour.
FWIW,如果你有一个支持 C99 的编译器,你可以使用 hh
长度修饰符来解决这个问题,比如
printf("%02hhx\n", (unsigned char)chars[0]);