struct und fread -> falscher wert in struct??
-
Hallo
Ich versuche gerade einen Bitmap-Header in ein Struct einzulesen, aber alle Werte bis auf den ersten werden falsch abgeglegt in der Structur!
Nach langen Stunden hab ich was über "Struct Padding" gefunden..
So wie es ausschaut werden nach den short int noch 2 byte eingefügt, aber warum werden die bytes nicht am structurende eingefügt sonder mittendrinn??1. Wie kann ich den Header richtig auslesen? -> Liegt der Fehler am fread?
2. Wenn ich das Bild auslesen will mit einer Pixel-Structur von 3Byte, wird dann das Bild ebenfalls falsch gelesen?Verwende Code:Blocks mit MinGW+GCC
Hier mein Code zum Testen
#include <stdio.h> #include <stdlib.h> #include <string.h> // #include <windows.h> void wait () { printf("\n Weiter mit Enter"); setvbuf(stdin,NULL,_IONBF,0); setvbuf(stdin,NULL,_IOFBF,BUFSIZ); getchar(); } struct bmp_header { unsigned short bfType; // 2 Byte ASCII-Zeichenkette "BM" -> Dezimal 19778 unsigned int bfSize; // 4 Byte Größe der BMP-Datei in Byte. (unzuverlässig) unsigned int bfReserved; // 4 Byte Reserve ist immer 0 unsigned int bfOffBits; // 4 Byte Offset der Bilddaten in Byte vom Beginn der Datei an. }; int main() { char pfad[] = "c:\\temp\\test.bmp"; FILE *fp; // File Pointer struct bmp_header bmp_info; // Variable mit BMP_Header Struktur /* ******************** ANFANG - Datei einlesen ****************** */ if ((fp=fopen(pfad, "rb")) == NULL) /*Datei zum Lesen öffnen */ { printf("\n Konnte Bitmap nicht öffnen "); return 1; /* keine Datei vorhanden */ } else { fread(&bmp_info,sizeof(bmp_info),1,fp); /* Einlesen eines Blocks */ fclose(fp); printf("bfType = %hu \n",bmp_info.bfType); printf("bfSize = %u \n",bmp_info.bfSize); printf("bfReserved = %i \n",bmp_info.bfReserved); printf("bfOffBits = %i \n\n",bmp_info.bfOffBits); printf("sizeof bfType = %i \n",sizeof(bmp_info.bfType)); printf("sizeof bfSize = %i \n",sizeof(bmp_info.bfSize)); printf("sizeof bfReserved = %i \n",sizeof(bmp_info.bfReserved)); printf("sizeof bfOffBits = %i \n",sizeof(bmp_info.bfOffBits)); } /* ******************** ENDE - Datei einlesen ****************** */ wait(); return 0; }
Ergebniss: (bfReserved sollte 0 sein.. ist es aber nicht)
http://img412.imageshack.us/img412/7025/struct.pngPS: bin noch nicht so gut in c
-
ich denke aus performance gründen wird dein header nach dem optimieren
struct bmp_header { unsigned int bfType; // 2 Byte ASCII-Zeichenkette "BM" -> Dezimal 19778 unsigned int bfSize; // 4 Byte Größe der BMP-Datei in Byte. (unzuverlässig) unsigned int bfReserved; // 4 Byte Reserve ist immer 0 unsigned int bfOffBits; // 4 Byte Offset der Bilddaten in Byte vom Beginn der Datei an. };
aussehen.
eigentlich muß man aber das structure packing explizit einschalten,also solte es normalerweise nicht passieren
-
Das eigentliche Problem nennt sich "Alignment" (nicht Padding).
Schau mal auf http://en.wikipedia.org/wiki/BMP_file_format
Dort steht, daß du die ersten beiden Zeichen ("BM") getrennt einlesen mußt, s. "Equivalent C-Language Header".
-
Hallo,
das Problem wurde schon genannt: Alignment/Padding. Wenn du dir die Größe deiner Struktur mit sizeof(struct bmp_header) anguckst, dann siehst du, warum die Daten nicht da landen, wo sie sollen. Mit einem#pragma pack(1) // Alignment abschalten. struct bmp_header { ... }; // Hier eventuell noch weitere Strukturen deklarieren. ... #pragma pack() // Alignment auf Anfangszustand setzen
Sollte das Problem behoben sein. Oder nimm gleich die in der windows.h verwendeten Strukturen, da ist das pragma pack ding schon um die Strukturen drum rum gebaut.
Gruß,
B.B.