C 十六进制格式给我额外的数字
C hexadecimal formatting giving me extra digits
我一直在开发一个小程序来转储文件的十六进制值,类似于 od
或 hexdump
,我 运行 遇到了一个问题打印值。对于某些十六进制值,主要是第二个数字为字母字符的值,它会在打印实际数字之前打印 6 个额外的 f 数字,而不是像我指定的那样只打印一个 2 宽度的值。我已经确认这些值本身在任何方面都不是意外的,是印刷弄乱了它。
代码:
int main(int argc, char* argv[]) {
FILE* dataFile = fopen(argv[1], "rb");
int byteCount = 0;
char currentByte = fgetc(dataFile);
while (currentByte != EOF) {
printf("%08d", byteCount);
do {
//print as hex
printf(" %02x ", currentByte);
//set up for next loop
currentByte = fgetc(dataFile);
byteCount++;
} while (currentByte != EOF && (byteCount) % 16 != 0);
printf("\n");
}
printf("%08d\n", byteCount);
}
输出:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
00000016 03 00 3e 00 01 00 00 00 10 6b 00 00 00 00 00 00
00000032 40 00 00 00 00 00 00 00 08 23 02 00 00 00 00 00
00000048 00 00 00 00 40 00 38 00 0d 00 40 00 1f 00 1e 00
00000064 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00
00000080 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00000096 ffffffd8 02 00 00 00 00 00 00 ffffffd8 02 00 00 00 00 00 00
00000112 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00
00000128 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00
00000144 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00
00000160 1c 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
00000176 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00
00000192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000208 fffffff8 34 00 00 00 00 00 00 fffffff8 34 00 00 00 00 00 00
有人知道这里发生了什么吗?
这里有几个问题。
char
完全不适合保存原始二进制数据,因为它具有 implementation-defined 符号并且通常是有符号类型,请参阅 Is char signed or unsigned by default?。事实上 char
应该只用于文本字符串。相反,您通常会使用 uint8_t
。然而……:
EOF
常量的类型为 int
,因此如果您打算将某些内容与 EOF
进行比较,则它必须为 int
类型。 fgetc
保证 return 个字符,就好像它们是 unsigned char
但转换为 int
- 碰巧的是, int
足够大以容纳一个的所有值unsigned char
所以这里可以用int
。
%x
printf
的说明符需要 unsigned int
.
修复:
char currentByte
-> int currentByte
printf(" %02x ", currentByte);
-> printf(" %02x ", (unsigned int)currentByte);
.
- 您必须始终检查
fopen
是否成功,完成后还 fclose
文件指针。另请注意,在专业程序中,直接在没有输入卫生的 argv 上调用 fopen
是不可接受的。您甚至不知道 argv[1]
是否存在 - 程序总体上需要更多的错误处理。
我一直在开发一个小程序来转储文件的十六进制值,类似于 od
或 hexdump
,我 运行 遇到了一个问题打印值。对于某些十六进制值,主要是第二个数字为字母字符的值,它会在打印实际数字之前打印 6 个额外的 f 数字,而不是像我指定的那样只打印一个 2 宽度的值。我已经确认这些值本身在任何方面都不是意外的,是印刷弄乱了它。
代码:
int main(int argc, char* argv[]) {
FILE* dataFile = fopen(argv[1], "rb");
int byteCount = 0;
char currentByte = fgetc(dataFile);
while (currentByte != EOF) {
printf("%08d", byteCount);
do {
//print as hex
printf(" %02x ", currentByte);
//set up for next loop
currentByte = fgetc(dataFile);
byteCount++;
} while (currentByte != EOF && (byteCount) % 16 != 0);
printf("\n");
}
printf("%08d\n", byteCount);
}
输出:
00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
00000016 03 00 3e 00 01 00 00 00 10 6b 00 00 00 00 00 00
00000032 40 00 00 00 00 00 00 00 08 23 02 00 00 00 00 00
00000048 00 00 00 00 40 00 38 00 0d 00 40 00 1f 00 1e 00
00000064 06 00 00 00 04 00 00 00 40 00 00 00 00 00 00 00
00000080 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00
00000096 ffffffd8 02 00 00 00 00 00 00 ffffffd8 02 00 00 00 00 00 00
00000112 08 00 00 00 00 00 00 00 03 00 00 00 04 00 00 00
00000128 18 03 00 00 00 00 00 00 18 03 00 00 00 00 00 00
00000144 18 03 00 00 00 00 00 00 1c 00 00 00 00 00 00 00
00000160 1c 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00
00000176 01 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00
00000192 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000208 fffffff8 34 00 00 00 00 00 00 fffffff8 34 00 00 00 00 00 00
有人知道这里发生了什么吗?
这里有几个问题。
char
完全不适合保存原始二进制数据,因为它具有 implementation-defined 符号并且通常是有符号类型,请参阅 Is char signed or unsigned by default?。事实上char
应该只用于文本字符串。相反,您通常会使用uint8_t
。然而……:EOF
常量的类型为int
,因此如果您打算将某些内容与EOF
进行比较,则它必须为int
类型。fgetc
保证 return 个字符,就好像它们是unsigned char
但转换为int
- 碰巧的是,int
足够大以容纳一个的所有值unsigned char
所以这里可以用int
。%x
printf
的说明符需要unsigned int
.
修复:
char currentByte
->int currentByte
printf(" %02x ", currentByte);
->printf(" %02x ", (unsigned int)currentByte);
.- 您必须始终检查
fopen
是否成功,完成后还fclose
文件指针。另请注意,在专业程序中,直接在没有输入卫生的 argv 上调用fopen
是不可接受的。您甚至不知道argv[1]
是否存在 - 程序总体上需要更多的错误处理。