2010-01-11 56 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'轉換爲其他數據,因爲它將它解釋爲回車/換行字符,而不僅僅是原始二進制數據。