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

Hex 在C中打印出char*数组的十六进制值会为二进制输入提供奇数值,hex,printf,c89,Hex,Printf,C89,有一个奇怪的问题一直困扰着我 该程序是用C89编写的,它一次将一个文件读入一个char*数组16字节(使用fread和sizeof(char)大小)。该文件用“rb”标志打开。然后将数组传递到一个函数中,该函数基本上接受16个十六进制值并将其粘贴到一个字符串中,每个值用空格分隔 这就是奇怪之处。该函数生成一个很好的十六进制转储,每次16字节,用于我的文本文件输入。但是如果我在一个小的位图图像上尝试它,它就会出错——我最终得到的输出是ffffff88而不是88 使用sprintf(“%02x”,输

有一个奇怪的问题一直困扰着我

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

这就是奇怪之处。该函数生成一个很好的十六进制转储,每次16字节,用于我的文本文件输入。但是如果我在一个小的位图图像上尝试它,它就会出错——我最终得到的输出是ffffff88而不是88

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


为什么这对某些文件有效,而对其他文件无效?

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

在C中,字符被视为有符号值,除非您将其指定为无符号。当你把参数传递给一个函数时,当这个参数恰好是一个字符时,它会被“填充”成一个常规整数的大小。如果您没有提示编译器这应该以无符号方式完成,那么128将变成0xFFFF80,依此类推

因此,符号扩展发生在打印格式化程序查看值之前。这意味着

printf("%02X", (unsigned) input[i]);
不会解决您的问题,因为输入[i]的值将被符号扩展,所以从128到255的所有值都被视为-127到-1,并变成0xFFFF80到0xFFFFFF,然后强制转换,而

printf("%02X", ((unsigned char *) input)[i] );
这会起作用,但有点笨拙,难以阅读。最好首先将输入[]的类型设置为无符号字符