fread into struct错误地读取数据

我试图将位图(.bmp)图像标题读入c中的struct

 typedef unsigned short WORD; typedef unsigned long DWORD; typedef struct _BITMAPFILEHEADER { WORD Type; DWORD Size; WORD Reserved1; WORD Reserved2; DWORD OffBits; } BITMAPFILEHEADER; 

我的代码读取位图文件

 FILE *fp; BITMAPFILEHEADER header; fp = fopen(file,"rb"); if (fp == NULL) { printf("cannot open file!\n"); return 1; } fread(&header, sizeof(BITMAPFILEHEADER), 1, fp); printf("Type: %02x\n", header.Type); printf("Size: %04x\n", header.Size); printf("Reserved: %02x\n", header.Reserved1); printf("Reserved: %02x\n", header.Reserved2); printf("Offset: %04x\n", header.OffBits); 

什么都应该是平等的:
键入: 0x424d
大小: 0x00060436
保留1: 0x00
保留2: 0x00
偏移量: 0x00000436

什么是真正的幸福(printf输出):
键入: 0x424d
大小: 0x0006
保留: 0x002
保留: 0x436
偏移量: 0x280000

(如果有帮助,我的操作系统是32位ubuntu)

在阅读这种文件时,我认为一种好的方法是首先将它们作为字节流( unsigned char )读取,然后,如果需要,根据适当的数据类型解释部分文件内容。

例如,在您的情况下,我将像这样定义BITMAPFILEHEADER结构:

 typedef struct _BITMAPFILEHEADER { unsigned char Type[ 2 ]; unsigned int Size; // Size of the BMP file in bytes unsigned char Reserved1[ 2 ]; unsigned char Reserved2[ 2 ]; unsigned int OffBits; // Starting address of the pixel array } BITMAPFILEHEADER; 

然后我会将标题内容读取为14个字节的块,最后,我将继续正确填充BITMAPFILEHEADER结构。

您可以在下面找到一个简单的程序,它读取BMP文件的标题并将其打印到屏幕上。

 int main ( ) { // Defines a few variables FILE* fp = 0; unsigned char h[ 14 ]; // Opens the BMP file fp = fopen( "img.bmp", "rb" ); if ( fp == NULL ) { printf( "Cannot open file\n" ); return -1; } // Reads the BMP header (14 bytes) fread( h, 14, 1, fp ); // Prints the header contents printf( "Type: %02x%02x\n", h[ 0 ], h[ 1 ] ); printf( "Size: %02x%02x%02x%02x\n", h[ 2 ], h[ 3 ], h[ 4 ], h[ 5 ] ); printf( "Reserved: %02x%02x\n", h[ 6 ], h[ 7 ] ); printf( "Reserved: %02x%02x\n", h[ 8 ], h[ 9 ] ); printf( "Offset: %02x%02x%02x%02x\n", h[ 10 ], h[ 11 ], h[ 12 ], h[ 13 ] ); return 0; } 

注1 – 填充:根据BMP文件格式规范,我们知道标头长度为14个字节,而printf( "%d", sizeof(BITMAPFILEHEADER) )由于填充而显示不同的(更大!)数字(请参阅对你的问题的评论)。

注2 – Endiannes:当分别将2或4个字节写入短或长时,您必须考虑到endiannes。 这意味着您必须知道如何将值写入文件(对于Bitmap标头,它们使用小端符号表示)以及机器如何处理它们(可能以小端符号表示)。