[C] Problem mit struct aus Datei lesen

randomize

Erfahrenes Mitglied
Hallo,

ich komme hier einfach nicht mehr weiter. Ich will aus einer Datei an einer bestimmten Position mit fread in eine Struktur lesen. Diese beginnt mit einem WORD, welches eine ID erhält, dann kommt ein DWORD, welches die Größe einer anderen struct erhält.
OS ist WinXP, Compiler Borland C++Builder.
Sodale, die struct sieht also in etwa so aus:
Code:
struct
{
  WORD ID;
  DWORD Groesse;
} s;
An der richtigen Position in der Datei bin ich, und lese die struct also nun so:
Code:
fread (&s, sizeof (s), 1, f);
f ist offensichtlich die Datei. ;)
Hat ja bis jetzt auch immer so geklappt, auch mit weitaus monströseren structs usw. usw. usw. keine Probleme gegeben.

Nun habe ich also mit einem Hex-Editor mal in die Datei gelunst, und habe für die ID einen Wert von 3. Der stimmt auch mit dem überein, was das Programm liest.
Aber den Wert für Groesse gibt das dumme Programm grundsätzlich mit 0x10000 an, wobei ich nunmal 150% weiß, dass er 0xAC sein muss. Das sagt der Hex-Editor, und dem vertraue ich in diesem Fall.
Was mich nur total aufregt ist, dass folgender Code die Groesse richtig ausliest, wobei er doch eigentlich nichts anderes macht (außer eben die Werte einzeln lesen, oder irre ich mich da...? Vielleicht ist auf Grund der fortgeschrittenen Tageszeit mein Hirn schon etwas angematscht):
Code:
fread (&s.ID, sizeof (s.ID), 1, f);
fread (&s.Groesse, sizeof (s.Groesse), 1, f);
Nebenbei bin ich dann in der Borland-Hilfe auf so einen Kram wie Data Alignment gestoßen und frage mich, ob das was damit zu tun haben kann. Es war offensichtlich auf 4-Byte eingestellt, habe das mal probeweise auf 2-Byte bzw. 1-Byte (also ausgeschaltet) eingestellt, hat aber nicht geholfen.

Ich wäre doch sehr dankbar für einen hilfreichen Tip!
Bye,
randomize
 
Ok, die Parameter bei fread sind schonmal vertauscht, außerdem halte ich die struct-Deklaration für ungünstig. Mach doch lieber:

Code:
struct Daten
{
  WORD ID;
  DWORD Groesse;
};

Daten s;

fread (&s, 1, sizeof (Daten), f);

So müsste es eigentlich funktionieren. Bist du sicher, dass du die richtigen Daten erwartest? Du erwartest 0xAC, das sieht aus wie ein Byte, dass aber in einem Word oder DWord (2 bzw. 4 Bytes) nicht so stehen wird, zumal auch noch die guten alten Intelkonventionen (vertauschen der Reihenfolge) Anwendung finden.
 
Original geschrieben von Dudadida
Ok, die Parameter bei fread sind schonmal vertauscht, außerdem halte ich die struct-Deklaration für ungünstig.
Ok ähm, also fread ist bei mir in etwa so definiert:
Code:
size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
"fread reads n items of data each of length size bytes from the given input stream into a block pointed to by ptr."

Also die Parameterreihenfolge scheint zu stimmen. Ich habe deine Version natürlich auch mal ausprobiert, macht interessanterweise nur keinen Unterschied. Und die struct-Deklaration war nur deshalb in dieser Form, weil ich nur diese eine gebraucht habe, gut das ist eher nebensächlich.

So, das da unten ist, was der Hex-Editor anzeigt, wobei das DWORD durch die leicht affige Farbgebung hinterlegt ist (wenn ich die Bedienung des Editors richtig verstanden habe, alles etwas Neuland für mich...). Wie auch immer, es muss jedenfalls 0xAC sein (die Datei ist nur ca. 150 Bytes groß, wie gesagt, dieser Wert beschreibt die Größe einer anderen struct innerhalb dieser Datei, daher macht 0x10000 keinen Sinn).
Original geschrieben von Dudadida
Du erwartest 0xAC, das sieht aus wie ein Byte, dass aber in einem Word oder DWord (2 bzw. 4 Bytes) nicht so stehen wird
Hmmm kannst du das bitte nochmal etwas genauer erklären?
So, nun mit dieser Intelkonvention, heißt das also ich muss die Bytefolge "umdrehen", um an den richtigen Wert zu kommen? Es wundert mich eben, wie man sieht, das WORD davor ist 0x0003, und das stimmt auch.

Danke vielmals! :)
randomize
 

Anhänge

  • unbenannt.gif
    unbenannt.gif
    7,7 KB · Aufrufe: 253
Zuletzt bearbeitet:
Also zu fread: Ok, das ist gerade eine rein formelle Sache. Man liest halt n Blöcke der Größe size. Ist in dem Fall auch vollkommen Wurscht, wie rum, aber wenn du mal versehentlich beim eigentlich byteweisen Einlesen einer großen Datei die Reihenfolge vertauschst, kommt vielleicht Müll raus.
In der Tat ist der Fehler seltsam, weil die Alternative, die du ja selbst schon probiert hast, funktioniert. Könnte mir wirklich nur denken, dass es mit dem Alignment zusammenhängt, aber da haben andere mehr Ahnung von.
Was die Intel-Konvention angeht, die kann damit ja eigentlich auch nicht viel zu tun haben, damit meine ich nur, dass die einzelnen Bytes einer Variable in umgekehrter Reihenfolge gespeichert werden. War noch ein bisschen müde heute morgen :rolleyes: .
 
NP @müde.

Ja also es regt mich sehr dolle auf, immernoch. Wobei ich es in VC++ und Borland C++Builder versucht habe, jedoch ohne Ergebnis (bzw. mit gleichem Erbegnis).
Ich wollte es eben mit structs machen (die oben beschriebene ist ja nicht die einzige), weil ich persönlich es irgendwie mehr mag als alle Variablen einzeln einzulesen.

Wenn nun also jemand noch etwas mehr über das Byte-Alignment weiß, bitte nicht zögern sich hier zu offenbaren, vielen Dank. :)
randomize
 
schau mal in den rückgabewert von fread ob er mit sizeof(s) übereinstimmt, hast du vielleicht die Datei nicht im binär modus geöffnet (hatte da schon ziemlich strange effekte) ?
Kannst du mal die Datei und den Code posten ?
 
Zurück