我的学校项目有问题。当我尝试在C程序中读取二进制文件中的一些十六进制数据时,我得到一些用F填充的数据
00 64 61 56 03 00 00 00 09 00 00 00 73 00 00 00
6A 69 75 FFFFFFE8 FFFFFFD1 5B FFFFFF8C FFFFFF93 73 FFFFFFAF 19 FFFFFF87 FFFFFFC1 4D FFFFFFFD FFFFFF93
FFFFFFDF FFFFFFBE FFFFFFA0 09 FFFFFFBE FFFFFFD4 FFFFFFEB FFFFFFDE FFFFFFD3 FFFFFFF9 FFFFFFBD FFFFFFE6 FFFFFFFA FFFFFFAA 7E 29
FFFFFFD3 FFFFFFE2 13 FFFFFFA5 3F FFFFFFA0 3A FFFFFFB2 50 53 3B 12 FFFFFFA1 39 FFFFFFA6 FFFFFF82
FFFFFFF7
虽然hexdump中的原始文件如下所示:
0000000 6400 5661 0003 0000 0009 0000 0073 0000
0000010 696a e875 5bd1 938c af73 8719 4dc1 93fd
0000020 bedf 09a0 d4be deeb f9d3 e6bd aafa 297e
0000030 e2d3 a513 a03f b23a 5350 123b 39a1 82a6
0000040 00f7
我不确定,为什么会这样。
我使用this代码测试了它:
int main()
{
char ch, file_name[25];
FILE *fp;
printf("Enter the name of file you wish to see\n");
fgets(file_name, sizeof(file_name), stdin);
file_name[strlen(file_name)-1] = 0x00;
fp = fopen(file_name,"rb"); // read binary mode
if( fp == NULL ) //error checking
{
perror("Error while opening the file.\n");
exit(EXIT_FAILURE);
}
printf("The contents of %s file are :\n", file_name);
int i;
while( ( ch = fgetc(fp) ) != EOF )
{
printf("%02X ",ch);
if( !(++i % 16) ) putc('\n', stdout);
}
fclose(fp);
putc('\n', stdout);
return 0;
}
答案 0 :(得分:2)
在将有符号整数值扩展为更大的整数类型时,您刚刚处理了处理器完成的符号扩展:
类型char
只有一个字节宽,而printf()
函数需要int
个参数(系统上有四个字节)。由于char
已在您的系统上签名,其他24位将填充符号位的副本,从而生成您在输出中看到的FFFFFF
模式。请注意,您的输出是正确的,除了FFFFFF
- 以十六进制数字大于或等于8
开头的所有字节的前缀。
您可以通过简单地将ch
声明为unsigned char
来避免这种情况。这将零扩展为int
,您的输出将是正确的。
答案 1 :(得分:1)
如果你使ch成为无符号字符,你将看不到符号扩展名(FF)。
答案 2 :(得分:0)
使ch成为无符号字符,因为它将二进制值视为有符号,MSB视为符号位。
答案 3 :(得分:0)
将文件作为二进制文件打开,然后尝试通过fgetc()
来处理文本文件,这可能不是一个好主意。相反,您可以使用fread()
来读取二进制文件。
这是我的解决方案:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main()
{
char file_name[25];
puts("Enter the name of file you wish to see");
fgets(file_name, sizeof (file_name), stdin);
file_name[strlen(file_name) - 1] = '\0';
FILE *fp;
fp = fopen(file_name, "rb"); // read binary mode
if(!fp) //error checking
{
perror("fopen()");
exit(EXIT_FAILURE);
}
fseek (fp, 0, SEEK_END); // non-portable
long fSize = ftell(fp);
rewind(fp);
printf("The contents of %s file are :\n", file_name);
uint8_t *ch = malloc(fSize); // assuming CHAR_BIT == 8
fread(ch, 1, fSize, fp);
int i;
for(i = 0; i < fSize; i++)
{
printf("%.2x ", ch[i]);
if(!((i + 1) % 16))
putchar('\n');
}
fclose(fp);
putchar('\n');
return EXIT_SUCCESS;
}
此代码已在我的机器上测试过,其输出与hex dump
的输出相同。请随时向我询问有关详细信息。