Forum: Compiler & IDEs struct aus Datei lesen mit C


von ME (Gast)


Lesenswert?

Hallo zusammen

Ich möchte eine binäre Datei mit einem C-Programm lesen. Die genaue 
Definition des Dateiformats (Offset und Länge der Daten) liegt mir vor*. 
Am Anfang der Datei steht ein Header mit verschiedenen Werten: Strings, 
Int, Float (ähnlich wie z.B. auch der Header einer wav-Datei).

Meine Frage:

Kann ich nun einfach in C eine struct definieren mit den selben 
Datentypen (d.h. gleich lang) in der selben Reihenfolge wie in der Datei 
und dann diese Daten direkt einlesen, d.h. einfach fread aufrufen mit 
einem Zeiger zu dieser struct?

Ich meine, mal gehört zu haben, dass es dem Compiler** überlassen ist, 
wie er die Daten innerhalb einer struct genau anordnet. Dann würde das 
folglich nicht gehen. Ist das so? Lässt sich das irgendwie umgehen (so 
dass also ich definiere wie die Anordnung ist)?

*genau handelt es sich um eine CHARMM DCD-Datei
**Ich verwende gcc 4.1.2 auf x86_64-redhat-linux

Im Voraus Danke für jede Hilfe.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sofern solche Dinge wie "endianness" geklärt sind, geht das direkte 
Einlesen der Struktur schon, nur sollte die gepackt sein, was je nach 
Compiler mit #pragma pack oder anderen Mechanismen erzielt werden kann.

http://gcc.gnu.org/onlinedocs/gcc/Structure_002dPacking-Pragmas.html

von ME (Gast)


Lesenswert?

Danke für den Hinweis. Meinst du etwa so:
1
#pragma pack(push)  /* push current alignment to stack */
2
#pragma pack(1)     /* set alignment to 1 byte boundary */
3
 
4
struct MyPackedData
5
{
6
    char Data1;
7
    long Data2;
8
    char Data3;
9
};
10
 
11
#pragma pack(pop)   /* restore original alignment from stack */

(kopiert von: 
http://en.wikipedia.org/wiki/Data_structure_alignment#Default_packing_and_.23pragma_pack)

Endianness ist in Ordnung. Das hab ich abgeklärt.

von Karl H. (kbuchegg)


Lesenswert?

ME schrieb:
> Danke für den Hinweis. Meinst du etwa so:

Dem Prinzip nach: ja

Allerdings solltest du eines beachten:
Alles was mit #pragma zu tun hat, ist der Natur der Sache nach immer 
compilerabhängig. Dein Anlaufpunkt für Informationen ist daher nicht 
Wikipedia, sondern das Helpfile deines Compilers.

von Rolf Magnus (Gast)


Lesenswert?

Rufus t. Firefly schrieb:
> Sofern solche Dinge wie "endianness" geklärt sind, geht das direkte
> Einlesen der Struktur schon, nur sollte die gepackt sein, was je nach
> Compiler mit #pragma pack oder anderen Mechanismen erzielt werden kann.

... und je nach Prozessor evtl. auch gar nicht geht.

von Nils S. (kruemeltee) Benutzerseite


Lesenswert?

Afaik geht das bei gcc aber so:
1
struct MyPackedData
2
{
3
    char Data1;
4
    long Data2;
5
    char Data3;
6
} __attribute__((packed));

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolf Magnus schrieb:
> ... und je nach Prozessor evtl. auch gar nicht geht.

Richtig, aber der Threadstarter wies freundlicherweise darauf hin, daß 
er x86 (mit 64 Bit) nutzt, und da geht das.

> **Ich verwende gcc 4.1.2 auf x86_64-redhat-linux

von Rolf Magnus (Gast)


Lesenswert?

Rufus t. Firefly schrieb:
> Rolf Magnus schrieb:
>> ... und je nach Prozessor evtl. auch gar nicht geht.
>
> Richtig, aber der Threadstarter wies freundlicherweise darauf hin, daß
> er x86 (mit 64 Bit) nutzt, und da geht das.

Sofern das für immer und ewig die einzige Architektur bleibt, mag das ok 
sein.

Rufus t. Firefly schrieb:
> was je nach Compiler mit #pragma pack oder anderen Mechanismen erzielt
> werden kann.

Da hättest du dir dann konsequenterweise das "je nach Compiler" sparen 
können, schließlich wies er ja freundlicherweise darauf hin, daß er gcc 
4.1.2 benutzt.

Nils S. schrieb:
> Afaik geht das bei gcc aber so:
>
> struct MyPackedData
> {
>     char Data1;
>     long Data2;
>     char Data3;
> } __attribute__((packed));

Ja. Allerdings hat man diese seltsame pragma-Sache vom 
Microsoft-Compiler irgendwann übernommen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.