Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

1

07.05.2012, 23:12

Binär Dateien lesen, kurzes Problem

Hallo,

ich versuche gerade einen Dateiheader einzulesen, allerdings klappt das nicht so ganz.
Das ganze sieht vom Prinzip her so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
struct header{
    unsigned int wert1; // eine Länge
    unsigned char wert2[4]; // eine Signatur aus 4 ASCII Zeichen
};

// ---------------------------

ifstream file(path.c_str(), ios::binary);

header h;

file.read(reinterpret_cast<char*>(&h), sizeof(header));


So wenn ich mir jetzt mal wert1 bzw. wert2 ausgeben lasse hat wert2 die Signatur die auch in der Datei steht (z.B. abcd). Aber in wert1 steht jetzt nicht die Zahl die ich erwarte, sondern 294840231 oder irgend sowas großes, obwohl in der Datei 00 00 00 09 (hex) = 13 steht (hab ich mit Hex Editor geprüft).
Das ganze funktioniert nur wenn ich wert1 als unsigned char[4] einlese und dann int(wert1[3]) ausgebe.
Ich dachte ich müsste evt. die Bytes vertauschen, bringt aber nichts. Liegt das am casten? Ich hab das noch nicht so oft gemacht und bräuchte da wohl gerade mal einen Tipp :)

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

07.05.2012, 23:25

Vermutlich wurde die Datei nichtmal korrekt geöffnet, dir fehlt das ios::in Flag...

Und mit deinem header struct musst du aufpassen von wegen Padding...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

08.05.2012, 06:53

Müsste man nicht eigentlich ios_base::in benutzen oder ifstream::in, wenn man ganz akkurat wäre? Ich hab' auch immer ios::in genutzt, aber laut Doku...
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

4

08.05.2012, 08:38

Wie kann ich dann schonmal den richtigen String haben dot?
Und ich glaube es liegt nicht daran wie ich die Datei öffne, in meinem tga loader mache ich das z.B. genauso.
Die 8 byte müssten doch von oben in das 8 byte große struct eingelesen werden? Es ist ja auch so, nur scheint das int falsch aufgebaut zu sein. Theoretisch sieht das jetzt so aus: 00000000 00000000 00000000 00001101 oder kurz 00 00 00 09 wobei das char char char char ist wenn ihr so wollt.

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

5

08.05.2012, 13:54

C-/C++-Quelltext

1
2
3
4
5
ifstream file(path.c_str(), ifstream::binary|ifstream::in);

oder

ifstream file(path.c_str(), ios::binary|ios::in);


Ändert beides nichts.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

08.05.2012, 14:07

Theoretisch sieht das jetzt so aus: 00 00 00 09

Und praktisch steht was in der Datei? Mal mit einem Hex-Editor geschaut?

Ich würde wie d0t allerdings auf Padding tippen. Dein Struct ist vermutlich keine 8 Byte groß, sondern 20. Lass Dir mal "sizeof" davon ausgeben.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

7

08.05.2012, 14:13

Zitat

Lass Dir mal "sizeof" davon ausgeben.


Hab ich, ist 8 byte groß.

Zitat

Und praktisch steht was in der Datei? Mal mit einem Hex-Editor geschaut?


Ja, hab ich auch schon geschrieben. Das sind die Werte.

Ich will ja quasi folgendes machen:

C-/C++-Quelltext

1
2
unsigned char ch[] = {0, 0, 0, 13};
unsigned int length = unsigned int(ch);


und auch hier kommt so ein komischer Wert raus (280102...). Mit atoi() kommt 0 raus.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

08.05.2012, 14:29

Du castest da eine Adresse in einen Int, das kann nicht gut gehen. Was du eigentlich meinst ist eher das:

C-/C++-Quelltext

1
unsigned int length = *reinterpret_cast<unsigned int*>(ch);


atoi macht an der Stelle keinen Sinn, schau Dir mal die Argumente und den Sinn von atoi an. (Tipp: Es geht dabei nicht um einen Array)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

  • »DeKugelschieber« ist der Autor dieses Themas

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

9

08.05.2012, 14:33

C-/C++-Quelltext

1
2
3
unsigned char ch[] = {0, 0, 0, 13};
unsigned int length = *reinterpret_cast<unsigned int*>(ch);
cout<<length<<endl;


Kommt keine 13 bei raus. Und klar geht mein cast ^^

Das mit atoi habe ich auch gerade entdeckt...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

08.05.2012, 14:35

Dein Cast macht aber nicht das, was Du von ihm willst. "ch" ist ein "Zeiger" und enthält NICHT den Wert "13" direkt, sondern der Speicher, auf den es zeigt, der enthält 13. Welches Endian-Format hat denn die Maschine, auf der Du da arbeitest und wie wurde die Datei erzeugt, die Du da liest? (Ich hoffe beides lautet "Big Endian", denn sonst macht das da alles keinen Sinn)

Denn die Byte-Folge 00 00 00 09 ist nicht 9 in Little Endian Format und damit auf einer Little Endian Machine eingelesen folglich 150994944.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »BlueCobold« (08.05.2012, 15:13)


Werbeanzeige