可能重复:
How to read a binary file in c? (video, images, or text)
我正在尝试使用C程序读取bmp file的内容。我能够阅读内容,但读取的值与我的预期相矛盾。我的代码是:
FILE *fp=NULL;
fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","r");
if(fp!=NULL)
{
printf("%c\n",fgetc(fp));
printf("%c\n",fgetc(fp));
printf("%c\n",fgetc(fp));
printf("%c\n",fgetc(fp));
printf("%c\n",fgetc(fp));
printf("%c\n",fgetc(fp));
}
else
printf("Error reading the file");
我只是在这里逐字节阅读,只是为了理解。前两个字节读取BM
这是正确的。接下来的四个字节读取*t
。预期值为40.请参阅format。有人可以解释发生了什么,如果我需要执行一些转换,如何获得值40
。
答案 0 :(得分:2)
我相信您的问题是您打开文件的方式:
fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","r");
“r”用于ASCII读取,您想以二进制打开它:
fp=fopen("C:\\Users\\Saurabh\\Pictures\\nice.bmp","rb");
修改强>
fgetc()
返回一个int,所以我尝试使用int来获取返回值,也希望以十六进制的形式看到结果,所以让我们使用十六进制输出格式:
FILE *readf;
int i;
unsigned int size = 0;
//Open file
readf = fopen("blackbuck.bmp", "rb");
i = fgetc(readf);
printf("%#x\n",i); // 0x42
i = fgetc(readf);
printf("%#x\n",i); // 0x4D
for(i=0; i<3; i++)
size |= fgetc(readf) << (i*8); // 0xC0036
此更新将前两个值作为0x42 0x4D,然后合并下一个3个字节,给出位图的大小(0xC0036 = 786486字节)
我使用此图片进行测试:http://people.sc.fsu.edu/~jburkardt/data/bmp/blackbuck.bmp
您可以看到结果具有bmp标头0x42 0x4d
的正确字节代码
the header field used to identify the BMP & DIB file is 0x42 0x4D in hexadecimal, same as BM in ASCII
答案 1 :(得分:1)
虽然我同意迈克的意见,你应该以二进制模式阅读这个文件,但它不应该引起你的问题。它最终会,但前6个字符不应该破坏,除非任何大小的字节包含10或13。
为了读取int,您可以执行类似
的操作int result;
fread(fp, sizeof (int), 1, &result);
但请注意,这不是便携式的。 (它假设32位整数和本机字节顺序,至少。由于它们的起源,BMP是小端的......如果你只是在大的时候一次性读取它,那么大小就会很古怪 - 端机。)
另一种方式:
unsigned long result = 0;
for (int i = 0; i < 4; ++i) {
result |= (unsigned long) fgetc(fp) << (i * 8);
}
至少应始终读取正确的字节数并考虑字节序。并且unsigned long
足以容纳任何32位数字,而int
(甚至无符号)则不能保证。