Streams (Binär)



  • Hallo,
    ich möchte in ein und der selben Datei verschiedene Datentypen binär ablegen.

    Dazu will ich die Datei wie folgt schreiben:
    NummernCode . Content ....

    Der NummernCode gibt dabei Preis, welcher Inhalt von welchem Datentypen nachfolgend erwartet werden kann. Zum Beispiel 1 für char / 2 für int usw.

    Mit ofstream im Binärmodus lässt sich dass ja denke ich machen?

    Mein Problem: Die Schreibfunktion von fstream sieht wie folgt aus:
    binaryfile.write((char*) &content, sizeof(datentyp));

    Das Ding ist, wieso muss ich meine datentyp Variable nach char casten?
    Wenn datentyp z.B. float ist dann möchte ich ja, dass der float in die Binärdatei geschrieben wird und durch den NummernCode später auch wieder als float ausgelesen werden soll und NICHT als char geschrieben werden soll.

    T233



  • Das Ding ist, wieso muss ich meine datentyp Variable nach char casten?

    a) weil byteweise geschrieben wird
    b) weil's das Interface von ofstream so will



  • Okay, danke.

    Wie könnte ich das "Problem" jetzt am besten lösen? - Gibt es in C++ nicht ähnlich wie in Java verschiedene Methoden/Funktionen (in der STL) um verschiedene Datentypen zu schreiben und zu lesen?

    Wenn ich jetzt write Funktion von fstream nutze, heißt dass ja (wenn es nicht irgendwelche fertige Pattern dafür gibt), dass wenn ich einen float habe, ich 4 Byte (32 Bit) einlesen müsste und den Bitsrom dann als float interpretieren, richtig? Gibt es dafür Funktionen?



  • Meinst du sowas?

    float my_float_value = 32222.60f;
    ofstream.write((char)&my_float_value, sizeof(float));
    
    ifstream.read(&my_float_value, sizeof(float));
    


  • Ich find das etwas besser.

    ofstream.write(reinterpret_cast<const char*>(&my_float_value), sizeof(my_float_value)); 
    
    ifstream.read(reinterpret_cast<char*>(&my_float_value), sizeof(my_float_value));
    


  • knivil schrieb:

    ofstream.write((char)&my_float_value, sizeof(float))
    

    Das muss dann aber so heißen:

    ofstream.write((char*)&my_float_value, sizeof(float))
    


  • Okay, das scheint zu funktionieren. Dann hatte ich es doch richtig. 🙂

    Ich verstehe nur leider nicht, warum es funktioniert. Könnte mir das jemand erklären?

    Nehmen wir mal an, ich habe folgendes:

    binaryfile.read((char*)&value, sizeof(float));
    

    Die nächsten 32 Bit die das Programm nun liest, sind definitiv auch eine abgespeicherte float. Aber woher weiß dass Programm, dass er nun diese sizeof(float)=32 Bit auch als float interpretieren soll? - Er könnte es ja auch genau so gut als 32 Bit Integer interpretieren.



  • T233 schrieb:

    Aber woher weiß dass Programm, dass er nun diese sizeof(float)=32 Bit auch als float interpretieren soll? - Er könnte es ja auch genau so gut als 32 Bit Integer interpretieren.

    Weil value vom Typ float ist. Wenn value int wäre, würde das Programm den Wert als int interpretieren.



  • Okay. Jetzt geht mir eine Lampe auf. 😃
    Danke für die Geduld. 👍



  • Noch eine kurze Frage:
    Wenn ihr in einer Schleife die Binärdaten auslest, wie würdet ihr am besten auf das EOF warten?

    Ich hab das jetzt so:

    while (!binaryfile.eof()) {
    binaryfile.read((char*) &tmp, sizeof(short));
    ...
    ...
    }
    

    Das Problem dabei ist, dass der letzte Datensatz vor dem EOF immer zwei mal ausgegeben wird, da er das EOF ja anscheinend erst erkennt, wenn er quasi schon "drüber" ist.


  • Mod

    So sollte (vom logischen Ablauf her) jede Leseschleife aussehen:

    while(binaryfile.read(...)) { ...verarbeiten ... }
    

    Dies benutzt den Rückgabewert von read:
    www.cplusplus.com/reference/istream/istream/read/
    und die Umwandlung von Streams in einem bool'schen Kontext (hier die erste der beiden):
    http://www.cplusplus.com/reference/ios/ios/operator_bool/
    http://www.cplusplus.com/reference/ios/ios/operator_not/

    Bei anderen Leseaktionen als read verhält es sich praktisch gleich, außer readsome, get (ohne Argumente), gcount und peek, wo der Rückgabewert eine etwas andere Bedeutung hat. An sich bleibt aber die logische Abfolge 1. Lesen, 2. Prüfen, 3. Verarbeiten auch bei diesen unverändert, bloß die Prüfung schaut anders aus.


Anmelden zum Antworten