Objekte in Datei schreiben und wieder lesen bringt zusätzlichen leeren Eintrag
-
Hallo zusammen,
im Rahmen meines Studiums sitze ich an einer Uebungsklausur und schreibe
Objekte in eine Datei. Das funktioniert auch ohne Probleme, Probleme bereitet
nur das Lesen aus der Datei: da wird ein "leeres" bzw. Objekt ohne Namen angelegt und in die STL List eingetragen.
Die Objekte sind von folgendem Typ:Town::Town(string &_name) { name = _name; size=1; money=1; research=1; luxuryGoods=1; rundenGespielt=0; }Funktion um Objekte aus der Liste zu holen:
{ ofstream outFile( "towns.dta", ios_base::binary | ios_base::out ); // write list<Town>::iterator iter; if(!outFile){ cerr << "Fehler Datei konnte nicht geoeffnet werden." << endl; } for(iter = allTowns.begin(); iter != allTowns.end(); ++iter ){ cout << "Sichern..." << endl; Town tempTown = *iter; tempTown.write(outFile); } outFile.close(); cout << " Die Staedte wurden gespeichert!\n\n"; break; }Funktion um die Objekte in die Datei zu schreiben:
ostream & Town::write(ostream & os) { os << name << '\0'; // write string // write 5 int starting at address of name os.write( reinterpret_cast< char* >(&size), 5 * sizeof( int ) ); return os; }Analog dazu zurück pushen in die Liste:
{ ifstream inFile( "towns.dta", ios_base::binary | ios_base::in ); // read if(!inFile){ cerr << "Fehler Datei konnte nicht geoeffnet werden." << endl; } else{ while (!(inFile.eof()) ) { Town tempTown(_name); cout << " Laden...." << endl; tempTown.read(inFile); allTowns.push_back(tempTown); } inFile.close(); }und die Funktion zum Lesen:
istream & Town::read(istream & is) { Town tempTown; getline( is, name, '\0' ); // read string // read 5 int starting at address of name is.read( reinterpret_cast< char* >(&size), 5* sizeof( int ) ); return is; }Ergebnis des ganzen ist, dass ich zwar alle Objekte in die Datei reinschreiben
kann, aber eins mehr als drin stehen ausgelesen wird.
Kann mir jemand helfen?
Wo ist mein Fehler?Gruß Alex
-
eof() schlägt erst Alarm, wenn du versuchst, jenseits des Dateiendes zu lesen. Das bedeutet, nach dem Einlesen des letzten Eintrags ist der Stream noch in Ordnung, im nächsten Schleifendurchlauf scheitert der read()-Aufruf und du hast einen gesperrten Stream und ein ungültiges Objekt - da mußt du abbrechen, bevor es weiterverarbeitet wird:
while (inFile) { Town tempTown(_name); cout << " Laden...." << endl; tempTown.read(inFile); if(!inFile) break; allTowns.push_back(tempTown); }oder noch besser:
Town tempTown; while(tempTown.read(inFile)) { cout<<"Laden..."<<endl; allTowns.push_back(tempTown); }PS: Und übrigens solltest du nicht nur das eofbit abfragen, sondern alle Fehlerbits - sonst landest du in einer Endlosschleife, wenn ein Lesefehler auftritt.