istream::tellg bricht Schleife ab



  • 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()=0

    Schö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! 🤡


  • Mod

    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 = -1
    

    Was 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 = -1
    

    Danke.



  • 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 = -1
    

    Vielen Dank für die bisherige Hilfe!



  • Ich wollte nur kurz mitteilen, dass ich gesehen habe, dass die Fehler nur unter bestimmten Bedingungen bzgl. des Inhalts der Datei kommen.

    Ich versuche den Fehler mal zu finden und schreibe, wenn ich eine Lösung habe.



  • Okay, bad und eof sind nicht gesetzt, aber fail ist gesetzt. Ich würde vermuten, dass in der Datei etwas zu lesen ansteht, das nicht zu dem Datentyp passt, in den Du einlesen willst. Also möglicherweise ist die Variable tag vom Typ int, in der Datei folgt aber keine Ziffer, irgendsoetwas muss es sein.


Anmelden zum Antworten