chars aus Binary File einlesen - EOF wird nicht gesetzt [gelößt und erklärt]
-
Hallo,
ich muss eine Datei einlesen (selbst erstellt in anderem Programmteil), die
einfach nur char Werte enthält. Öffne ich die Datei bspw. im Editor werden die
Chars korrekt angezeigt. Schaue ich mir im Debugmodus den Inhalt des ifstream buffers an,
enthält er die gewünschten Werte. Von dieser Seite müsste eigentlich alles in Ordnung sein.
Leider stürzt das Programm aber beim Einlesen dieser Datei ab, weil es die Schleife zum Beenden des Einlesevorgangs nicht verlässt.Ich habe lange gesucht und Bücher Internet und das Forum befragt, aber sehe den Fehler einfach nicht.
Es wäre eine super Sache, wenn irgendjemand mir weiterhelfen könnte. DankeMein Code sieht wie folgt aus
namespace boost::filesystem = fs; list<char> ReadFile ( const fs::path filePath ){ fs::basic_ifstream<char> fileStream( filePath, ios::in | ios::binary ); // Throw exceptions in case badbit or failbit is set fileStream.exceptions( ios_base::badbit | ios_base::failbit ); list<char> returnList; while (!fileStream.eof()) { char c; // the program is aborted here when it tries get() after all chars of the file have been read // instead it should throw an exception or even better - end the loop if (fileStream.get( c ).fail() == false) returnList.push_back( c ); } return returnList; }und hier der Aufruf der Methode
try{ list< char > charList = ReadFile( filePath ); } catch( const ios_base::failure& e) { /// irgendwas } catch( const exception& e) { /// irgendwas }Ich habe mehrere Probleme:
- EOF wird nicht gesetzt. Die Testdatei enthält 6 char Einträge, und ich kann im Debugmodus die Schleife
auch genau 6 mal betreten, beim 7ten Leseversuch stürzt das Programm ab - es werden keine Exceptions geworfen
- auch wenn ich ios_base::eof zu den gewünschten Exceptions hinzufüge wird keine Exception geworfen.
Hat irgendjemand vielleicht eine Idee woran das liegen könnte ?
Danke schonmal...
- EOF wird nicht gesetzt. Die Testdatei enthält 6 char Einträge, und ich kann im Debugmodus die Schleife
-
ich korrigieren mich:
Setzte ich die Schleife direkt in einen Try Catch Block
wird eine exception geworden
( ich habe auch versucht boost::filesystem::filesystem_error exceptions zu catchen)mit dem Code
catch( const ios_base::failure& e){ std::cout << "type: " << typeid(e).name() << std::endl; std::cout << "message: " << e.what() << std::endl; }gibt sie folgendes von sich preis:
type: NSt8ios_base7failureE
message: basic_ios::clearDas hilft mir aber leider nicht dabei weiter, zu verstehen was an meinem Code
falsch ist...
-
Nach einiger Testerei hier die Erklärung für das Verhalten:
der Befehl
// Werfe eine Exception sobald eines der Flags gesetzt wird fileStream.exceptions( ios_base::badbit | ios_base::failbit ); try{ while (!fileStream.eof()) { char c; // get( c ) setzt das Failbit wenn kein Zeichen mehr gelesen werden kann und returned EOF // sobald das Failbit gesetzt ist, wird die Exception geworfen und die Schleife verlassen if ( (fileStream.get( c ).fail() ) == false) content.push_back( c ); } } catch( const ios_base::failure& e){ std::cout << "type: " << typeid(e).name() << std::endl; std::cout << "message: " << e.what() << std::endl; }Sofern mit Exceptions gearbeitet wird macht das die While Schleife überflüssig
Lässt man die Exceptions ausgeschaltet ist der Folgende Code korrekt
while (!fileStream.eof()) { char c; // Versuche das nächste Zeichen als char einzulesen. Tritt hierbei kein Fehler auf füge es zur Liste hinzu. // Kann kein weiteres Zeichen gelesen werden wird das Failbit und EOF gesetzt // beim nächsten Durchlauf der While Schleife wird die Eingangs-Bedinung nicht // mehr erfüllt und der Einlesevorgang beendet if ( (fileStream.get( c ).fail() ) == false) content.push_back( c ); } }Fazit:
- Wenn man mit Exceptions arbeitet ist eine While Schleife zur Abfrage des EOF Bits überflüssig,
weil die Exception geworfen wird sobald das Bit gesetzt wird. - Es wird bei jedesmal eine Exception geworfen, sobald das Ende einer Datei erreicht ist, wenn man
.exceptions( ios_base::failbit );setzt.
( Failbit gesetzt bedeutet: nächste Operation geht schief )- Es empfiehlt sich, nur eine Exception zu werfen, wenn das badbit gesetzt ist,
.exceptions( ios_base::badbit );weil auf diese Weise nur im wirklichen Fehlerfall Exceptions geworfen werden, und ansonsten ´
die oben gezeigte Schleife sich um das Einlesen bis zum Dateieinde kümmert.
( Badbit gesetzt bedeutet: Stream ist nicht mehr verwendbar )- Wenn man ohne Exceptions arbeitet kann man das Failbit benutzen um zu überprüfen, ob ein Zeichen
korrekt eingelesen wurde, und eine While Schleife die EOF abfragt, um das Dateiende zu finden
Vielleichts hilfts ja irgendjemand mal weiter

Gruß
zitroneneis
- Wenn man mit Exceptions arbeitet ist eine While Schleife zur Abfrage des EOF Bits überflüssig,