Daten in struct einlesen, Endekennung
-
Hallo zusammen,
ich möchte aus einer Datei Daten in eine Struktur einlesen und auf dem Bildschirm ausgeben. Es gibt in meinem Minimalbesipiel einen winzigen Fehler (Endekennung wird mit eingelesen), der mir das Leben bei der Weiterverarbeitung der Daten schwer macht.
Hier mein Minimalbeispiel:#include <iostream> #include <fstream> using namespace std; struct test { int alter; char name[50]; } person[10]; int main( void ) { int n=0; ifstream eingabe_datei; eingabe_datei.open("person.dat", ios::binary|ios::in); while (!eingabe_datei.eof()) { eingabe_datei >> person[n].alter >> person[n].name; cout << person[n].alter << " " << person[n].name << endl; n++; } eingabe_datei.close(); }Die einzulesende Datei person.dat sieht so aus:
**
30 Paul
32 Stefan
**Nach Ablauf des obigen Programms bekomme ich aber als Bildschirmausgabe
**
30 Paul
32 Stefan
0
**
Nun zum Fehler: Die Null am Ende stört, da ich die Daten weiterverarbeiten möchte. Ich denke sie kommt von der Endekennung des zuletzt eingelesenen
char name[50].
Hat jemand eine Idee wie ich das Einlesen der Struktur korrekt machen kann ?Besten Dank für die Hilfe.
Jo
-
Hallo liebe Community,
habe das Problem nun selbst gelöst:
dieser Weg für das Einlesen (Zeile 18) funktioniert einwandfrei und die zusätzliche Null wird nicht ausgegeben:
while(eingabe_datei >> person[n].alter >> person[n].name ) { cout << person[n].alter << person[n].name << endl; n++; }Warum mein stilistisch besserer Ansatz mit
while (!eingabe_datei.eof())nicht funktionierte, weiss ich immer noch nicht und würde mich freuen, wenn jemand da eine Idee hätte.
Danke und Grüße, Jo
-
Du öffnest im binary mode. Wenn du Text einliest ist der normale Modus angebracht. Ich gehe mal davon aus dass es daran liegt.
-
Hallo RedPuma,
danke für den Tipp, das war auch mein erster Gedanke, aber daran liegt es nicht...wenn man das Binary Flag weglässt ist das Programmverhalten in diesem Fall identisch.
-
jo911 schrieb:
Warum mein stilistisch besserer Ansatz mit
while (!eingabe_datei.eof())nicht funktionierte, weiss ich immer noch nicht und würde mich freuen, wenn jemand da eine Idee hätte.
Danke und Grüße, JoDas ist doch ganz einfach: End of file gibt genau dann
truezurück, wenn der Stream am Ende der Datei ist.EDIT: Ist in deiner Datei wirklich ein Leerzeichen nach dem letzten Namen oder spinnt das Forum?
Bei mir funktionierteofin Visual C++ mit einer korrekten Datei wie erwartet.
-
Hallo,
auch ich verwende VC++ (2005). Die Eingabe-Datei ist korrekt, kein Leerzeichen am Ende.
Muss ein anderes Problem sein.
-
Dein "stilistisch besserer Ansatz" ist ein beliebter Anfängerfehler. Das EOF-Bit des Streams wird erst gesetzt, nachdem eine Leseoperation auf das Dateiende gestoßen ist. Nach der letzten erfolgreichen Leseoperation ist das noch nicht der Fall, also wird die Schleife danach noch einmal betreten. Die Leseoperation in dieser Schleife schlägt dann fehl, das EOF-Bit wird gesetzt und person[n] nicht verändert, daher kommt dann die letzte Ausgabe.
Es ist in der Tat üblich, in solchen Fällen
while(datei >> daten) { ... }zu schreiben. Das prüft dann nicht nur auf das EOF-Bit, sondern auch auf badbit und failbit, so dass man auf die Art nicht in einer Endlosschleife landen kann. Ist wirklich nur die Prüfung auf eof gemeint, so geht
while((datei >> daten).eof()) { ... }...aber das ist nur selten sinnvoll.
Übrigens solltest du in der Schleifenbedingung auch abprüfen, dass du nicht über das Arrayende hinaus schreibst oder besser gleich eine std::deque oder einen std::vector benutzen. Warum du das Array als globale Variable anlegst, ist mir auch nicht klar; so was ist ziemlich schlechter Stil.