2010-01-11 59 views
0

我想读取位于头部的位图,但fread正在为我跳过字符。Fread跳过字符读入对象

我使用这个的typedef在我的头:

#include <windows.h> // Used for other 
#include <cstdio> 
typedef struct tagBITMAPHEADER{ 
    WORD wFileType;  
    DWORD dwFileSize;  
    WORD dwReserved;  
    WORD dwReserved2;   
    DWORD dwBmpDataOffset; 
    DWORD dwBmpHeaderSize; 
    DWORD dwWidth;  
    DWORD dwHeight; 
    WORD wPlanes;  
    WORD wBitsPerPixel; 
    DWORD dwCompression; 
    DWORD dwBitmapDataSz; 
    DWORD dwHRes;  
    DWORD dwVRes;  
    DWORD dwColors; 
    DWORD dwImpColors;  
} BITMAPHEADER, *PBITMAPHEADER; 

而且在我的代码,我只使用一个简单的fopen和FREAD二进制。

#include "ImageLoader.h" 
BITMAPHEADER pbhFileInfo; 
FILE *fBitmap = fopen(FileName,"rb"); //Open file in read/binary 
if (fBitmap) //File is now open 
{ fread(&pbhFileInfo,sizeof(BITMAPFILEHEADER),1,fBitmap); 
    fclose(fBitmap); 
} 

虽然我的位图 '424DF25A0D'(十六进制)开始,前两个变量读取似乎跳过 'F25A'

wFileType =覆盖0x4D42 dwFileSize = 0x0000000d

任何想法可能会起来?

在此先感谢。

+0

所以你偶然发现了struct padding。你还应该阅读关于排序。如果你真的希望你的代码独立于数据大小,struct padding,并且处理所有类型的字节顺序,你应该手动解码这些信息并把它放在你的头文件结构中。这显然是更多的工作,但也更可靠。 – 2010-01-11 03:18:03

回答

1

在我看来,以这种方式使用结构是非常不明智的。是的,在这种情况下,您可以使用编译器特定的编译指示得到您想要的内容。如果您正在编写Windows设备驱动程序或其他已针对特定平台特有的其他内容,我会考虑采用可接受的解决方案。

但是这是以标准格式加载文件。它是可以在任何环境中运行的代码。个人而言,我会编写代码将数据从字符数组中提取出来,然后用手将结果放入结构中,而不是依靠编译器以正确的方式布局结构,这样fread会神奇地把所有的小数据放在正确的地方。

+0

由于这是一个特定于Windows的头文件提供的定义,Windows代码很可能在Windows环境中运行。你仍然有一个好点。 – 2010-01-11 03:56:34

+0

是的,不是说我很完美。很明显,我仍然在克服一些'noob-ish'的错误。我只是不明白为什么不同的结构会起作用。很多例子把这个结构分成了两个,然后我的cpp文件工作得很好。 – rpgFANATIC 2010-01-11 13:50:17

+0

是的,我决定遵循你的建议。感谢大家的帮助! – rpgFANATIC 2010-01-16 23:10:30

1

您的结构正在被编译器对齐。

您似乎在使用Visual C++。您struct定义之前添加此行:

#pragma pack(push 1) 

而且定义

#pragma pack(pop) 

要了解之后这条线,看到Why isn’t sizeof for a struct equal to the sum of sizeof of each member?

+0

您的意思是#pragma pack(1)? 我玩过它(是的,我正在使用VS2k5),这似乎是帮助。 – rpgFANATIC 2010-01-11 03:03:01

+0

'#pragma pack(1)'会起作用,但也会影响后面的定义。 – 2010-01-11 03:09:00

+0

看起来像阅读数据对齐也是对我的好处。感谢您的指导! – rpgFANATIC 2010-01-11 03:13:11

0

你以二进制方式打开文件?如果不是,那么这是你的问题,因为它会将424DF25A0D中的'0D'转换为其他数据,因为它将它解释为回车/换行字符,而不仅仅是原始二进制数据。