mikrocontroller.net

Forum: Compiler & IDEs struct aus Datei lesen mit C


Autor: ME (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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_002dPa...

Autor: ME (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis. Meinst du etwa so:
#pragma pack(push)  /* push current alignment to stack */
#pragma pack(1)     /* set alignment to 1 byte boundary */
 
struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
};
 
#pragma pack(pop)   /* restore original alignment from stack */

(kopiert von: 
http://en.wikipedia.org/wiki/Data_structure_alignm...)

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nils S. (kruemeltee) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Afaik geht das bei gcc aber so:
struct MyPackedData
{
    char Data1;
    long Data2;
    char Data3;
} __attribute__((packed));

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.