2010-01-11 3 views
0

Я пытаюсь читать в растровом изображении, начиная с его заголовка, но fread пропускает символы для меня.Чтение пропущенных символов в объекте

Я использую этот ЬурейеЕ в моем заголовке:

#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; 

И в моем коде, я просто использовать простой Еореп и 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' (HEX), первые две переменные читать, кажется, чтобы пропустить 'F25A'

wFileType = 0x4d42 dwFileSize = 0x0000000d

Любая идея может быть?

Заранее спасибо.

+0

Итак, вы наткнулись на прокладку структуры. Вы также должны прочитать о предисловии. Если вы действительно хотите, чтобы ваш код не зависел от размеров данных, отладки структуры и работы со всеми типами endianness, вы должны вручную декодировать информацию и поместить ее в свою структуру заголовка. Это, очевидно, больше работы, но и более надежной. –

ответ

1

По-моему, очень неразумно использовать структуру таким образом. Да, вы можете получить то, что хотите в этом случае, с помощью специальной справки для компилятора. Я бы счел приемлемым решение, если вы пишете драйвер устройства Windows или что-то еще, что уже было очень специфично для конкретной платформы.

Но это загрузка файла в стандартном формате. Это код, который может работать в любой среде.

Лично я бы написал код, который вытащил данные из массива символов и вложил его в структуру вручную вместо того, чтобы полагаться на структуру, которая должна быть выстроена в нужном порядке компилятором, так что волшебство будет волшебным поместите все маленькие бит данных в нужные места.

+0

Поскольку это формат для Windows с конкретным файлом заголовка Windows, обеспечивающим определение, этот код, скорее всего, будет работать в среде Windows. Вы все еще хорошо разбираетесь. –

+0

Да, я не говорю, что я совершенен. Очевидно, что я все еще перебираю ошибки «noob-ish».Я просто не мог понять, почему будет работать другая структура. Множество примеров разбило эту структуру на две, а затем мой файл cpp работал отлично. – rpgFANATIC

+0

Да, я решил следовать твоему совету. Спасибо всем за помощь! – rpgFANATIC

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

+0

'#pragma pack (1)' будет работать, но также повлияет на последующие определения. –

+0

Похоже, мне также полезно читать информацию о выравнивании данных. Спасибо за направление! – rpgFANATIC

0

Вы открыть файл в двоичном режиме? Если нет, то это ваша проблема, так как он преобразует '0D' в 424DF25A0D в некоторые другие данные, поскольку он интерпретирует его как символ возврата каретки/строки, а не только сырые двоичные данные.

Смежные вопросы