[gelöst] ifstream::fail() liefert false trotz vorherigem .setstate(ios_base::failbit)



  • _Bongo schrieb:

    mgaeckler schrieb:

    Ich zitiere Deine Quelle

    Sets the stream error flags state in addition to currently set flags. Essentially calls clear(rdstate() | state). May throw an exception.
    Parameters

    Hervorhebung von mir.

    VG

    Das habe ich auch so verstanden. Aber was ist mit dem Beispiel-Code? Da wird das auch so gemacht. Ausserdem habe ich es ja auch schon in einem kurzen Testprogramm ausprobiert. Da übergebe ich ein ifstream-Objekt an eine Funktion, setze dort dieses Flag, der Prozessor springt zurück hinter den Aufruf und das Bit ist gesetzt.

    Nur im eigentlichen Programm ist etwas anders und ich weiß nicht was.

    Ich zitiere nochmal:

    #include <iostream>
    #include <sstream>
    
    int main()
    {
        std::ostringstream stream;
    
        if (!stream.fail()) {
            std::cout << "stream is not fail\n";
        }
    
        stream.setstate(std::ios_base::failbit);
    
        if (stream.fail()) {
            std::cout << "now stream is fail\n";
        }
    
        if (!stream.good()) {
            std::cout << "and stream is not good\n";
        }
    }
    

    Wo siehst Du hier das logische NOT (!) beim Aufruf von setstate ?



  • Darüber mache ich mir Gedanken, wenn der EIP des Prozessors mal in den Zweig mit der Abfrage

    if(ifsDeltaDatei.fail())
    

    verzweigt.

    Mein Problem ist, dass das was ich da vorhabe in einem Testprogramm funktioniert und in meinem "richtigen" Programm nicht - der essentielle Code ist derselbe.

    In Zeile 12 deines Posts wird doch das Bit gesetzt. Und danach springt der Prozessor auch in die Verzweigung die ich oben notiert habe. Verlagere ich die Abfrage ausserhalb der setzenden Funktion, verzweigt er nicht mehr.



  • Was ich sehe, sieht in Ordnung aus. Lann es sein, daß Deine Funktion deltaParsen einfach zu früh beendet?

    else if(token == "}")
        {
            // Objekttiefe nimmt ab
            if(!--iLevel)
                is.setstate(ios_base::failbit);
            iLevel--;
    
            return is;
        }
    

    Diese Teil bricht ab sobald das erste } gefunden wurde. Egal, was in iLevel drinnen steht. Ist das wirklich Absicht? Außerdem decrementierst Du iLevel zweimal.

    EDIT: Wo wird eigentlich iLevel initialisiert?

    VG



  • Das zweite Dekrement steht da nur, weil ich das eine mal auskommentiert habe. Ich bin mit dem Debugger dadurch. Die Zeile in der das Bit gesetzt wird, wird definitiv durchlaufen. Nach dem Return in diesem Zweig, wird in der aufrufenden Funktion die nächste Zeile über die Funktion deltaParsen verarbeitet. Aber vorher wird halt auf das gesetzte Bit geprüft.

    iLevel ist eine static-Variable.



  • _Bongo schrieb:

    Das zweite Dekrement steht da nur, weil ich das eine mal auskommentiert habe. Ich bin mit dem Debugger dadurch. Die Zeile in der das Bit gesetzt wird, wird definitiv durchlaufen. Nach dem Return in diesem Zweig, wird in der aufrufenden Funktion die nächste Zeile über die Funktion deltaParsen verarbeitet. Aber vorher wird halt auf das gesetzte Bit geprüft.

    iLevel ist eine static-Variable.

    Wie soll man in Deinen Code 'nen Fehler finden, wenn Du nicht den Code postest, der funktionieren soll?



  • Du hast bereits das auskommentiert was ich fälschlicher Weise auskommentiert gelassen habe. Alles andere was auskommentiert ist, hat nix mit dem Fehler hier zutun.



  • _Bongo schrieb:

    Du hast bereits das auskommentiert was ich fälschlicher Weise auskommentiert gelassen habe. Alles andere was auskommentiert ist, hat nix mit dem Fehler hier zutun.

    Also: Wenn Deine nicht initialisierte Variable iLevel zufällig 1 enthält während ein } gefunden wurde, setzt Du das failbit decrementiert möglicherweiser nochmal iLevel und kehrt ansonsen SOFORT zurück. Der Aufrufer überprüft dann auch SOFORT das failbit.

    Richtig?



  • Statische Variablen werden nicht zufällig mit irgendwas initialisiert. Statische Variablen werden immer mit 0 initialisiert.



  • _Bongo schrieb:

    Statische Variablen werden nicht zufällig mit irgendwas initialisiert. Statische Variablen werden immer mit 0 initialisiert.

    OK, hast recht, find ich trotzdem nicht schön.



  • Was wäre denn schöner? Die Variable muss statisch sein. Sollte ich die jetzt trotzem mit 0 initialisieren, weil es schöner ist. 😃



  • Aus dem von Dir geposteten Code kann ich jedenfalls keinen Fehler finden, der Dein Problem verursachen könnte. Prüfe also, was mit Deinem Streamobjekt zwischem dem Setzen und dem Prüfen des failbits passiert. Prüfe ebenfalls, ob die Library, die Du benutzt, wirklich alles richtig macht. Wobei ich eher den Fehler bei Dir vermute, denn die Behandlung der statebits ist einfach zu simpel, als daß man das falsch machen könnte. Allerdings kann JEDER Mist bauen.

    VG



  • Also, ich habe das setstate jetzt direkt an den Anfang der Funktion gesetzt und den Stream zurückgegeben - keine Veränderung. Ich schreibe jetzt nochmal ein kleines Testprogramm, das eigentlich nix anderes macht aber trotzdem funktioniert.



  • _Bongo schrieb:

    Was wäre denn schöner? Die Variable muss statisch sein. Sollte ich die jetzt trotzem mit 0 initialisieren, weil es schöner ist. 😃

    Alles, was man explizit im Quelltext angibt, ohne daß es die Performance beeinträchtigt, ist schöner als irgendwelche impliziten Annahmen, die vielleicht nicht jeder kennt. Macht den Quelltext verständlicher und daher leichter wartbar.

    VG



  • _Bongo schrieb:

    Also, ich habe das setstate jetzt direkt an den Anfang der Funktion gesetzt und den Stream zurückgegeben - keine Veränderung. Ich schreibe jetzt nochmal ein kleines Testprogramm, das eigentlich nix anderes macht aber trotzdem funktioniert.

    Debugge einfach mal in die Library rein. Vielleicht ist wirklich dort der Fehler.

    VG



  • Dann dürfte es aber doch in diesem Programm hier auch nicht funktionieren:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    istream& test(istream&);
    
    int main()
    {
    	ifstream ifs("Testdatei.txt");
    	string strBuffer;
    
    	if(!ifs.fail())
    		cout << "Datei okay" << endl;
    	else
    		cout << "Datei im Arsch" << endl;
    
    	test(ifs);	// hier drin wird das Bit gesetzt
    	if(!ifs.fail())
    		cout << "Datei okay" << endl;
    	else
    		cout << "Datei im Arsch" << endl;
    
    	ifs.clear();
    	if(!ifs.fail())
    		cout << "Datei okay" << endl;
    	else
    		cout << "Datei im Arsch" << endl;
    
    	cin.get();
    	return 0;
    }
    
    istream& test(istream& is)
    {
    	is.setstate(ios_base::failbit);
    	return is;
    }
    

    Das läuft aber.



  • Wie ich schon schrieb, ich halte es für unwahrscheinlich, daß es an der Lib liegt.

    An dem Code, den Du gepostet hast, liegt es aber wohl auch nicht.



  • Habe den Fehler gefunden. Du hattest Recht. Der Compiler hat die Zeile innerhalb der Verzweigung nicht angemeckert aber einfach nicht übersetzt. Er ist nicht in die Verzweigung abgebogen, weil dort kein Maschinencode hinterlegt wurde. Habe die Zeile

    !ifsDeltaDatei.failbit;
    

    durch

    ifsDeltaDatei.clear();
    

    ersetzt.

    Jetzt verzweigt er. Ich danke dir für deine Hilfe.

    Grüße
    Kai



  • 👍 🙂


Anmelden zum Antworten