FREAD成结构是不正确的数据 [英] fread into struct reads data incorrectly
问题描述
我想在C读取位图(.bmp)映像头成结构
。
I am trying to read a bitmap (.bmp) image header into a struct
in c.
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct _BITMAPFILEHEADER {
WORD Type;
DWORD Size;
WORD Reserved1;
WORD Reserved2;
DWORD OffBits;
} BITMAPFILEHEADER;
我的code读取位图文件
My code to read the bitmap file
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: 0×00
结果
RESERVED2: 0×00
结果
偏移: 0x00000436
搜索
What everything should equal:
Type: 0x424d
Size: 0x00060436
Reserved1: 0x00
Reserved2: 0x00
Offset: 0x00000436
什么是真正happning(printf的输出):结果
类型: 0x424d
结果
大小: 0x0006
结果
版权所有: 0x002
结果
版权所有: 0x436
结果
偏移: 0x280000
搜索
What is actually happning (printf output):
Type: 0x424d
Size: 0x0006
Reserved: 0x002
Reserved: 0x436
Offset: 0x280000
(我的操作系统是32位的Ubuntu是否有帮助)
(my os is 32-bit ubuntu if that helps)
推荐答案
在阅读这种文件我认为一个好的办法是先读它们作为字节(流 unsigned char型
),然后,如果和当需要时,可以根据适当的数据类型的文件的内容除$ p $角部
When reading this kind of files I think a good approach is to first read them as a stream of bytes (unsigned char
) and then, if and when needed, to interpret part of the file contents according to the proper data types.
在你的情况,比如,我会定义 BITMAPFILEHEADER
结构是这样的:
In your case, for instance, I would define the BITMAPFILEHEADER
struct like this:
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文件的头并打印到屏幕上。
Below you can find a simple program that reads the header of a BMP file and prints it onto the screen.
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 ))
将显示一个不同的(大于!)数量由于填充(见注释你的问题)。
NOTE 1 - Padding: From the BMP file format specification, we know that the header is 14-byte long while a printf( "%d", sizeof(BITMAPFILEHEADER) )
will show a different (greater!) number due to padding (see comments to your question).
注2 - 字节序::当分别写2个或4个字节为一个或长或短,你必须要考虑到字节序。这意味着你必须知道价值是如何写入到文件(位图头,他们是用小尾数符号重新presented),以及他们如何通过你的机器(可能在小尾数表示)。治疗
NOTE 2 - Endiannes: When writing 2 or 4 bytes into a short or long respectively, you have to take into account endiannes. This means that you have to know how values are written into the file (as for the Bitmap header, they are represented using little endian notation) and how they are treated by your machine (probably in little endian notation).
这篇关于FREAD成结构是不正确的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!