Problem beim Einlesen einer Struktur



  • Hallo,

    folgendes:

    void LiesSaetze(aartVektor &av)
    {
    	ifstream dat(datei);
    	if(!dat)
    		return;
    
    	aartSatz tmp; cout << "tellg = " << dat.tellg() << endl;
    	dat.read(reinterpret_cast<char*>(&tmp), sizeof(aartSatz));
    
    	while (!dat.eof())
    	{
    		av.push_back(tmp); cout << "tellg = " << dat.tellg() << endl;
    		dat.read(reinterpret_cast<char*>(&tmp), sizeof(aartSatz));
    	}
    }
    

    erzeugt diese Ausgabe:
    tellg = 0
    tellg = 18
    tellg = 34
    tellg = 50
    tellg = 66

    Die eingelesene Struktur ist eine Klasse mit vier Membervariablen vom Typ int. Das Erzeugen der Datei geschieht analog durch write(..., sizeof(aartSatz).
    Interessanterweise ist der allererste Satz 2 Byte länger als die restlichen, wie man den tellg-Ausgaben oben entnehmen kann. Trotzdem funktioniert das Einlesen, aus irgendeinem Grund wird das richtigerweise berücksichtigt ...
    Ein Problem habe ich jetzt jedoch, wenn ich per random - Zugriff mit einem Vielfachen von sizeof(aartSatz) einen Eintrag überschreiben will, dann 'lande' ich nämlich 2 Byte zu früh.
    Wieso werden beim ersten Satz diese 2 Byte zu viel geschrieben? Sie landen eines hinter dem ersten Integer und eines hinter dem dritten Integer und haben den Wert 0x0D.
    Das Schreiben der Datei geht übrigens:

    ofstream dat(datei, ios::out | ios::app);
    	dat.write(reinterpret_cast<char*>(&as), sizeof(aartSatz));
    


  • Du solltest vielleicht noch ios_base::binary setzen. Ansonsten werden bestimmte Zeichen von fstream interpretiert, und nicht einfach gelesen/geschrieben. Das gleiche gilt auch für das Schreiben der Datei.



  • Tachyon schrieb:

    Du solltest vielleicht noch ios_base::binary setzen. Ansonsten werden bestimmte Zeichen von fstream interpretiert, und nicht einfach gelesen/geschrieben. Das gleiche gilt auch für das Schreiben der Datei.

    Guter Hinweis. Allerdings ist für heute Feierabend 🙂 Morgen werde ich das aber ausprobieren. Verwundert hat mich halt, daß nur der allererste Satz zu lang wird ...

    Ließ mir keine Ruhe bis morgen! That's it!!!

    Ich danke Dir sehr vielmals!
    Kann ich Dir irgendwie ein Bier mailen?



  • Hi jetzt mal ne Frage zu diesem Codestück (auch wenns nicht richtig dazu passt. Wollte aber keinen neuen Thread aufmachen :))

    Belli schrieb:

    ifstream dat(datei);
    	if(!dat)
    		return;
    

    Warum kann ich

    if(!dat)

    schreibn? welchen Operator muss ich da bei meiner eigenen Klasse überladen das das bei mir au funktioniert?

    Mfg Pingu-Group



  • Pingu-Group schrieb:

    ...schreibn? welchen Operator muss ich da bei meiner eigenen Klasse überladen das das bei mir au funktioniert?

    Mfg Pingu-Group

    In diesem Falle wird der Cast-Operator nach void* überladen.



  • Tachyon@loggedoff schrieb:

    In diesem Falle wird der Cast-Operator nach void* überladen.

    Wieso eigentlich nicht bool ? Damit man es nicht aus Versehen implizit in einen Integer konvertiert?



  • Nexus schrieb:

    Tachyon@loggedoff schrieb:

    In diesem Falle wird der Cast-Operator nach void* überladen.

    Wieso eigentlich nicht bool ? Damit man es nicht aus Versehen implizit in einen Integer konvertiert?

    Jup. Das gute "Safe Bool Idiom". 😉

    Dann würde nämlich z.B. sowas gehen:

    int kacke;
    std::cin << kacke; //Bitshift!
    


  • Okay. Bei überladenem Cast-Operator muss man generell sehr aufpassen, da man dadurch seine Freiheiten immer sehr ausweitet.

    Bei einfachen Klassen, die keine arithmetischen Operatoren überladen, würde operator bool also nichts machen. Genau gesehen könnte man aber bei std::ostream auf die folgende Idee kommen und hat damit vielleicht sogar einen ungültigen Zeiger: :p

    void* ptr = std::cin;
    


  • Nexus schrieb:

    Okay. Bei überladenem Cast-Operator muss man generell sehr aufpassen, da man dadurch seine Freiheiten immer sehr ausweitet.

    Bei einfachen Klassen, die keine arithmetischen Operatoren überladen, würde operator bool also nichts machen. Genau gesehen könnte man aber bei std::ostream auf die folgende Idee kommen und hat damit vielleicht sogar einen ungültigen Zeiger: :p

    void* ptr = std::cin;
    

    Ja, aber dafür muss man schon ziemlich böswillig sein. Um >> mit << zu verwechseln brauchts nur mal einen vergessenen Druck auf die Shift-Taste.


Anmelden zum Antworten