为何十六进制printf会打印4字节值?如何修复hexDump函数输出异常?
修复HexDump函数的符号扩展问题
原函数代码
void hexDump(char *buf, size_t size) { for(int i = 0; i < size; i++) { if(i % 4 == 0) { printf("\n"); } printf("%02x ", buf[i]); }
问题现象
函数前两行输出正常,但后续行出现多余的fffff前缀,例如:
24 00 00 00 00 0a 04 04 ffffffe8 ffffffd9 22 63 00 00 00 00 02 00 0a 00 ...
而通过gdb查看buf的真实内容,对应位置的字节是0xe8、0xd9,并非带前缀的值。
问题原因
char类型在多数编译器中默认是有符号类型。当buf中的字节值大于0x7F(即最高位为1)时,会被解析为负数。调用printf("%02x")时,char类型会被自动提升为int类型,负数的符号位会进行扩展,导致原本的8位字节被填充为32位的负数表示(如0xe8变成0xffffffe8),最终输出多余的前缀。
修复方案
有两种可行的修复方式:
- 修改参数类型为无符号字符指针
将char *buf替换为unsigned char *buf,确保所有字节都被当作无符号值处理,避免符号扩展:
void hexDump(unsigned char *buf, size_t size) { for(int i = 0; i < size; i++) { if(i % 4 == 0) { printf("\n"); } printf("%02x ", buf[i]); }
- 在输出时强制转换为无符号字符
如果不想修改函数参数类型,可以在printf时将buf[i]强制转换为unsigned char,截断符号扩展的影响:
void hexDump(char *buf, size_t size) { for(int i = 0; i < size; i++) { if(i % 4 == 0) { printf("\n"); } printf("%02x ", (unsigned char)buf[i]); }
修复效果
修改后,0xe8、0xd9这类字节会正确输出为e8、d9,不再出现多余的前缀,与gdb中查看的真实内容一致。
内容的提问来源于stack exchange,提问作者Yaroslav Yasynytskyi
相关产品推荐
相关产品推荐

