problem mit ifstream



  • Hi, ich habe folgendes komisches Verhalten (Visual Studio 2005):

    ich habe eine Klassenvariable
    ifstream m_file

    ich öffne ein file
    m_file.open(dateiname)
    und lese mit
    getline(m_file,line)
    die Datei aus

    am Ende
    schließe ich mit
    m_file.close();

    durch ein externes Ereignis wird das ganze wiederholt.
    Allerdings schlägt gleich das Zeile auslesen fehlt.

    irgendwie ist der Stream scheinbar kaputt.
    wenn ich die internen zustände nach dem ersten und dem zweiten Öffnen vergleiche, gibt es Unterschiede zB _MyState (oder so ähnlich)

    Ist das ein Bug in der STL-implementierung?

    zusammengefasst sieht der Ablauf also so aus:

    ifstream file;
    file.open("test.txt");
    string line;
    while( getline(file, line) )
    {
      // machwas
      cout << line << endl;
    }
    file.close();
    file.open("test.txt");
    while( getline(file, line) )     
    {                              
      // machnochwas              // wird nie aufgerufen getline scheitert
      cout << line << endl;
    }
    

    Edit:
    fehlendes e eingefügt
    cout eingefügt



  • Vielleicht hilft ja ein file.clear() zwischendurch, falls das eof-flag noch gesetzt ist...



  • vlad_tepesch schrieb:

    ich habe eine Klassenvariable
    ifstream m_file

    Ist das eine Membervariable, weil du wirklich eine Datei über einen einzelnen Methodenaufruf hinweg offenhalten musst? Oder gibt es die nur, weil du hier und da eine Datei einlesen musst und dir jeweils die Definition einer lokalen Variablen ersparen wolltest?



  • MFK schrieb:

    Ist das eine Membervariable, weil du wirklich eine Datei über einen einzelnen Methodenaufruf hinweg offenhalten musst?

    ja
    Eine Callbackfunktion einer Klasse wird zyklisch aufgerufen und schickt bei jedem Aufruf eine weitere Zeile.

    Unter bestimmten Umtänden soll das ganze resettet werden und von vorn beginnen.
    eventuell aber auch mit einer anderen Datei.

    MFK schrieb:

    Oder gibt es die nur, weil du hier und da eine Datei einlesen musst und dir jeweils die Definition einer lokalen Variablen ersparen wolltest?

    nein.

    Aber das ist ja nicht der Kern der sache.
    Das gepostete Minimalbesipiel zeigt das ganze ja auch (wenn man das fehlende e noch einfügt)

    Decimad schrieb:

    Vielleicht hilft ja ein file.clear() zwischendurch, falls das eof-flag noch gesetzt ist...

    hilft auch nix.

    Ich hab auch schon ein seekg(0) probiert

    Ich habs jetzt erst mal so gelöst, dass ich das member als Pointer eingebunden habe und ein komplett neues Objekt erzeuge.

    Aber mich würde dennoch die Ursache oder eine Lösung des ursprünglichen Problemes interessieren.

    Edit:
    kann das denn jemand mit einem anderen compiler nachvollziehen?



  • Bei mir funktionockelt das wunderbar (vs2010). Aber auch Vs2005 würde ich das zutrauen. Ich könnte mir vorstellen, dass der Fehler irgendwo anders vergraben liegt.



  • Decimad schrieb:

    Bei mir funktionockelt das wunderbar (vs2010). Aber auch Vs2005 würde ich das zutrauen. Ich könnte mir vorstellen, dass der Fehler irgendwo anders vergraben liegt.

    Naja, ich habe genau oben geposteten Code in eine leere main gepackt.
    das 2. while überspringt er komplett.



  • Und welche Error-Flags sind anschließend gesetzt?



  • vlad_tepesch schrieb:

    Naja, ich habe genau oben geposteten Code in eine leere main gepackt.
    das 2. while überspringt er komplett.

    Auch mit einem file.clear() zwischen close und open?



  • MFK schrieb:

    vlad_tepesch schrieb:

    Naja, ich habe genau oben geposteten Code in eine leere main gepackt.
    das 2. while überspringt er komplett.

    Auch mit einem file.clear() zwischen close und open?

    ja.
    auch wenns nach dem Open gemacht wird -> keine Auswirkung.



  • Also was ich ausprobiert habe, sah jetzt so aus:

    int main(int argc, char* argv[])
    {
    	std::ifstream file;
    
    	file.open("test.txt");
    	std::string line;
    	while( std::getline(file, line) )
    	{
    	  std::cout << line << '\n';
    	}	
    	file.close();
    
    	std::cout << '\n';
    
    	file.open("test.txt");
    	while( getline(file, line) )    
    	{                              
    		std::cout << line << '\n';
    	}
    	file.close();
    
    	return 0;
    }
    

    ... und rattert mir wie erwartet zweimal die Datei auf die Konsole.



  • Ah, ok.
    **
    Das clear löst das Problem doch.**

    Ich hatte erst im Testprogramm vergessen, im 2. open einen gültigen Pfad anzugeben und danach das zwischenzeitlich eingefügte seek zu entfernen, dass ich auch noch vor dem open eingefügt hatte.

    Danke Leute!

    edit:
    aber ohne das clear gehts wirklich nicht.



  • Möge der Stream mit uns sein!



  • Mögen die Leute endlich lernen, dass Streams RAII können. Ist ja schrecklich.



  • PiOhneKomma: Nun nicht so hart sein, das war sein runtergestripptes Beispiel, dass wohl bei n Durchläufen zumindest mal die File-Pointer-Position als Zustand mitschleift oder so ähnlich, wir haben ja gar nicht so genau gesehen, was er nun dort tut. Sicherlich ginge das natürlich auch mit RAII und nem auto_ptr auf dem Heap 😉



  • Wozu nen auto_ptr?



  • Na um bloß keine Leaks zu bekommen!



  • Wo willst du denn da Leaks bekommen?



  • Löschen bitte.



  • Na auf dem Heap!



  • Ich sehe keine Heap-Allokationen.


Log in to reply