在C中打印出char *数组的十六进制值会给出二进制输入的奇数值

时间:2009-11-20 22:12:08

标签: hex printf c89

这是一个奇怪的问题,一直困扰我。

该程序是用C89编写的,它一次将文件读入一个16字节的char *数组(使用fread和sizeof(char)的大小)。该文件与“rb”标志一起打开。然后将数组传递给一个函数,该函数基本上取16个十六进制值并将其粘贴到一个字符串中,每个值用空格分隔。

这就是奇怪的地方。该函数产生一个漂亮的十六进制转储,一次16个字节,用于我拥有的文本文件输入。但是如果我在一个小的位图图像上尝试它会搞砸 - 我最终在字符串中输出像ffffff88而不是88.

使用sprintf(“%02x”,input [i])将十六进制值放入输出字符串中;在循环中。

为什么这对某些文件而不是其他文件正常工作?

2 个答案:

答案 0 :(得分:11)

在C中,char被视为有符号值,除非您将其指定为unsigned。当你将参数传递给一个函数时,似乎当参数恰好是一个char时,它被“填充”为常规整数的大小。如果你不想让编译器知道这应该以无符号方式完成,那么128变为0xFFFFFF80,依此类推。

因此,符号扩展发生在print formatter查看该值之前。这意味着什么

printf("%02X", (unsigned) input[i]);

将无法解决您的问题,因为input [i]的值将被符号扩展,因此从128到255的所有值都被视为-127到-1并且变为0xFFFFFF80到0xFFFFFF,然后强制转换,而

printf("%02X", ((unsigned char *) input)[i] );

会做到这一点,但有点笨拙且难以阅读。最好使输入类型[]首先是unsigned char。

答案 1 :(得分:9)

您看到的是从charint的符号扩展结果,使用unsigned char *或在转换为int之前转换为unsigned char(隐式地?)执行应该解决你的问题。