istream::tellg bricht Schleife ab
-
Hallo alle zusammen,
in folgendem Code wird die Schleife immer abgebrochen, wenn Zeile 5 eingefügt wird. Das heißt, sie läuft ein mal durch, Zeile 5 wird auch noch ausgeführt, aber dann bricht sie ab.
while(datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin){ if(monat==auswahl_monat && jahr==auswahl_jahr){ cout << id << "\t" << tag << "\t" << uhrzeit1 << "\t" << uhrzeit2 << "\t" << pause << "\t" << soll << "\t" << diffmin << endl; id++; pos = datei.tellg(); } }Wer weiß rat bzw. kann mir erklären, warum das so läuft.
Schöne Grüße
Julius
-
Bitte gib uns ein vollständiges Beispiel, an dem wir deinen Fehler nachvollziehen können. Gerade da Zeile 5 doch eher unverdächtig aussieht ist hier zu erwarten, dass etwas unerwartetes passiert
.
-
Hallo Julius,
tellg liefert die Position im Streambuf. Es ist aber nicht garantiert, dass dieses Feature auch von jedem Streambuf (der quasi unter/hinter dem Stream liegt) unterstützt wird. Stell Dir vor, die Daten, die Du da liest kämen über eine Serielle Schnittstelle, also immer nur 1 Zeichen nach dem anderen - da macht so etwas wie tellg und seek keinen Sinn.
In diesem Fall liefert tellg den Wert -1. In Deinem Fall scheint es so zu sein, dass tellg zusätzlich den istream in den Fehlerzustand setzt.
Schaue bitte mal nach welchen Wert 'pos' annimmt.Mit welcher Entwicklungsumgebung arbeitest Du?
Gruß
Werner
-
Ich komme mit dem Code irgendwie nicht durch den Spamschutz.
Vorher kommt jedenfalls:
int id = 1; long pos; eingeben_jahr(); eingeben_monat(); auswahl_jahr = jahr; auswahl_monat = monat; system("cls"); cout << "ID\tTag\tBeginn\tEnde\tPause\tSoll\tUberstunden" << endl << endl; ifstream datei("liste");pos 236 (die Stelle, an der sich der putpointer befindet?).
Und ich bin Anfänger und verstehe deinen Post nicht richtig (Werner).
Ich benutze Windows 7, Codeblocks und den GNU GCC Compiler.
Falls ich völlig an der Frage vorbeigeantwortet habe, bitte ich um Tadel.

Schöne Grüße und Danke
Julius
-
Hallo Julius,
lass es mich noch mal zusammen fassen: Du behauptest, dass Dein Programm fuinktioniert, also mehr als einen Datensatz aus der Datei liest und ausgibt, wenn die Zeile 5 in Deinem ersten Listing auskommentiert ist. Aktivierst Du dann die Zeile 5
pos = datei.tellg();, dann läuft die Schleife nur noch genau einmal durch - und das obwohl 'pos' den Wert von 236!=-1 annimmt.
Also um ehrlich zu sein - Du musst Dich vertan haben. Prüfe das, was ich geschrieben habe, bitte noch mal so nach, ob das auch passt.
Ansonsten füge folgende Zeilen ein:while(datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin){ if(monat==auswahl_monat && jahr==auswahl_jahr){ cout << id << "\t" << tag << "\t" << uhrzeit1 << "\t" << uhrzeit2 << "\t" << pause << "\t" << soll << "\t" << diffmin << endl; id++; cout << "> datei.fail()=" << datei.fail() << endl; // <- neu pos = datei.tellg(); cout << "> pos=" << pos << endl; // <- neu cout << "> datei.fail()=" << datei.fail() << endl; // <- neu } }.. und berichte uns, wie die Ausgabe ist.
js707 schrieb:
Und ich bin Anfänger und verstehe deinen Post nicht richtig (Werner).
und wenn Du konkrete Fragen stellst, kann ich die auch gerne beantworten

Gruß
Werner
-
Hey Werner,
danke für die Hilfe.
Folgende Ausgabe kommt heraus:
> datei.fail()=0
> pos=236
> datei.fail()=0Schöne Grüße
Julius
-
Hallo Julius,
.. dann darf das Einfügen oder Weglassen von Zeile 5 auch keinen Unterschied machen, was die Anzahl der Schleifendurchläufe betrifft. Da ist irgendwas anderes nicht ok, was Du uns noch nicht gesagt hast.
Gruß
Werner
-
Schau mal in SeppJs Post und Signatur. Oder in meine. Oder halte dich an den guten Ton im Netz und in Foren wie diesen und lies dir vorm Posten die mit wichtig gekennzeichneten Threads durch. Wird dich alles zu der gleichen Erkenntnis führen, dass man dir mit den paar Infos die du lieferst nicht helfen kann.
-
Vielleicht lohnt es sich, die Werte noch mal außerhalb der Bedingung auszugeben.
-
Die Abbruchbedingung in der while-Schleife erscheint mir zu kompliziert. Verlagere die Eingabe aus der Datei in die Schleife und prüfe dort auf Abbruch oder Fortsetzung. Entweder verwende eine logische Variable im while-Kopf oder break / continue innerhalb der Schleife.
-
berniebutt schrieb:
Die Abbruchbedingung in der while-Schleife erscheint mir zu kompliziert.
Häh? Die Abbruchbedingung ist einfach der Status des Streams. Solange der Stream okay ist, wird die Schleife ausgeführt.
-
Meine vielleicht unmassgebliche Meinung: Lieber ein paar Codezeilen mehr mit besser kontrollierbarem Ablauf des Programmes. Dann brauche ich keine solche Fragen hier zu stellen!

-
berniebutt schrieb:
Meine vielleicht unmassgebliche Meinung: Lieber ein paar Codezeilen mehr mit besser kontrollierbarem Ablauf des Programmes. Dann brauche ich keine solche Fragen hier zu stellen!

Wie würdest du es denn besser machen?
So?
while(true) { datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin; if (!datei) break! rest_der_schleife(); }Das wäre schon ein Antipattern.
-
Moin,
ich habe jetzt zum Ausprobieren eine einfachere Bedingung im Schleifenkopf genommen und die Bedingung weggelassen.
Folgender Code:
while(id<4){ datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin; pos = datei.tellg(); cout << "ID = " <<id << " datei.fail() = " << datei.fail() << " pos = " << pos << endl; id++; }Ergibt folgende Ausgabe:
ID = 1 datei.fail() = 0 pos = 44 ID = 2 datei.fail() = 1 pos = -1 ID = 3 datei.fail() = 1 pos = -1Was bedeutet das?
Schöne Grüße
Julius
-
Das bedeutet, dass ID 2 und 3 bei dir fehlerhaft waren und die Position deshalb -1 ist, also so gesehen keine Positionen sind.
-
Das bedeutet, dass Du nur einmal ordentlich aus der Datei lesen konntest. Beim zweiten Leseversuch geht irgendwas schief.
Gib das auch noch mal vor dem tellg aus, damit man sieht, ob der Stream beim Lesen oder erst beim tellg - Aufruf auf fehlerhaft gesetzt wird.
-
SeppJ schrieb:
while(true) { datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin; if (!datei) break! rest_der_schleife(); }Das wäre schon ein Antipattern.
Schöner Anticode zum Abgewöhnen!

Der Fragesteller scheint aber langsam dahin zu kommen, wo er hin will?
-
Neuer Code:
while(id<4){ datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin; cout << "VOR tellg:\tID = " <<id << " datei.fail() = " << datei.fail() << " pos = " << pos << endl; pos = datei.tellg(); cout << "NACH tellg:\tID = " <<id << " datei.fail() = " << datei.fail() << " pos = " << pos << endl; id++; }Ausgabe:
VOR tellg: ID = 1 datei.fail() = 0 pos = 0 NACH tellg: ID = 1 datei.fail() = 0 pos = 44 VOR tellg: ID = 2 datei.fail() = 1 pos = 44 NACH tellg: ID = 2 datei.fail() = 1 pos = -1 VOR tellg: ID = 3 datei.fail() = 1 pos = -1 NACH tellg: ID = 3 datei.fail() = 1 pos = -1Danke.
-
Also beim zweiten Lesen geht etwas schief, da danach das failbit gesetzt ist ...
Gib bitte zusätzlich zu datei.fail() noch datei.eof() und datei.bad() aus.
-
Neuer Code:
while(id<3){ datei >> tag >> monat >> jahr >> uhrzeit1 >> uhrzeit2 >> pause >> soll >> diffmin; cout << "VOR tellg:\tID = " <<id << " datei.eof()=" << datei.eof() << " datei.bad()=" << datei.bad() <<" datei.fail()=" << datei.fail() << " pos = " << pos << endl; pos = datei.tellg(); cout << "NACH tellg:\tID = " <<id << " datei.eof()=" << datei.eof() << " datei.bad()=" << datei.bad() <<" datei.fail()=" << datei.fail() << " pos = " << pos << endl; id++; }Ausgabe:
VOR tellg: ID = 1 datei.eof()=0 datei.bad()=0 datei.fail()=0 pos = 0 NACH tellg: ID = 1 datei.eof()=0 datei.bad()=0 datei.fail()=0 pos = 44 VOR tellg: ID = 2 datei.eof()=0 datei.bad()=0 datei.fail()=1 pos = 44 NACH tellg: ID = 2 datei.eof()=0 datei.bad()=0 datei.fail()=1 pos = -1Vielen Dank für die bisherige Hilfe!