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

Koz*_*aki 7 printf hex c89

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

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

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

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

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

Jus*_*eff 11

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

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

printf("%02X", (unsigned) input[i]);
Run Code Online (Sandbox Code Playgroud)

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

printf("%02X", ((unsigned char *) input)[i] );
Run Code Online (Sandbox Code Playgroud)

会做的伎俩,但有点笨拙和难以阅读.最好使输入类型[]首先成为unsigned char.


rsp*_*rsp 9

你看到的是从符号扩展的结果char,以int使用unsigned char *或铸造unsigned char之前为int投(隐含?)执行应该解决您的问题.