Frage zu while schleife
-
Hallo zusammen
Ich lese aktuell das Buch von "Ulrich breymann" "Der C++ Programmierer"
(c++11 aktualisiert)Ich bin jetzt bei "Datei Ein und Ausgabe" mit ifstrema / ofstream
Hier der Code vom Beispiel
/* cppbuch/k2/dateianzeigen.cpp Beispiel zum Buch von Ulrich Breymann: Der C++ Programmierer; Hanser Verlag Diese Software ist freie Software. Website zum Buch: http://www.cppbuch.de/ */ #include <string> #include <fstream> #include <iostream> using namespace std; int main() { string quelldateiname; cout << "Quelldatei? "; cin >> quelldateiname; ifstream quelle(quelldateiname); // Objekt für Eingabestrom if (!quelle) { // Fehlerabfrage cerr << quelldateiname << " kann nicht geöffnet werden!\n"; } else { // Lesen der Datei und Anzeige der Zeilen while (quelle) { string zeile; getline(quelle, zeile); cout << zeile << endl; } } } // Datei wird am Programmende automatisch geschlossen.Ich verstehe nur nicht, wie die Whileschleife (Zeile 22)"while(quelle){...}" funktioniert.
Warum steht da "quelle" im Bedingungsteil und nicht ein true oder false wert (bsw i < 7);Ich ahne, dass es etwas mit "Container und Schleifen" zu tun hat. aber mir fällt nichts ein.
Danke im voraus
-
Durch Operatoren-Überladung, in diesem Fall
bool operator()), kann in C++ ein Objekt zutrueundfalseausgewertet werden. Inwhile(quelle)wird implizit diese Operator-Methode aufgerufen.Wenn du den Stream öffnest und dabei kein Fehler auftritt, dann ist dein Stream-Objekt in einem gültigen Zustand und liefert
true. Wenn nun das Ende des Files erreicht wird oder ein Fehler auftritt, dann wird ein Fehler-Flag gesetzt und dein Objekt wird zufalseausgewertet.while ( quelle )bedeutet also, dass das Programm die Schleife ausführen soll, solange das Programm weiteren Input lesen kann.
-
Das hat nichts mit der while-Schleife an sich zu tun sondern mit dem ifstream. Der ifstream ist in bool konvertierbar und gibt dann zurueck, ob er im "good" Status ist, d.h. ob alle bisherigen Operationen erfolgreich waren.
Die Schleife bedeutet daher "Solange alles okay ist ...".Allerdings hat der Code einen Logikfehler. Es wird zuerst geprueft, ob der Stream good ist, danach eingelesen und das ungeprueft eingelesene ausgegeben. Richtig waere ...
string zeile; while(getline(quelle, zeile)) cout << zeile << '\n';... also einlesen -> pruefen -> verarbeiten
Oder (meiner Meinung nach schoener):
for(string zeile; getline(quelle, zeile);) cout << zeile << '\n';
-
OK. das ist mir nun klar.
Jedoch muss doch etwas mit quelle passieren, das es nachher nicht mehr true ist, sondern false. was macht getline() mit quelle, dass es nachher false ist.
-
Sebastian Müller schrieb:
OK. das ist mir nun klar.
Jedoch muss doch etwas mit quelle passieren, das es nachher nicht mehr true ist, sondern false. was macht getline() mit quelle, dass es nachher false ist.
Wenn es aus der Datei nichts mehr zu lesen gibt dann ist sie im EOF-Zustand und nicht mehr good.
-
Also gibt es im Objekt quelle so eine Art Lesezeiger für Bits oder Zeilen.
Wenn der am schluss angekommen ist, ist die Datei nicht mehr good (false).habe ich recht?
-
Sebastian Müller schrieb:
Also gibt es im Objekt quelle so eine Art Lesezeiger für Bits oder Zeilen.
Wenn der am schluss angekommen ist, ist die Datei nicht mehr good (false).habe ich recht?
Ja, der Stream ist dann im EOF-Zustand (EOF steht für end of file) und somit nicht mehr
good.
-
Sebastian Müller schrieb:
Also gibt es im Objekt quelle so eine Art Lesezeiger für Bits oder Zeilen.
Wenn der am schluss angekommen ist, ist die Datei nicht mehr good (false).habe ich recht?
Nein, falsch.
Ein fstream hat eine Art Lesezeiger, ja. Aber Computer arbeiten mit ganzen Bytes und Zeilen sind bloß eine Konvention für Menschen. Dieser Zeiger gibt also eine Byteposition in der Datei an.
Ein Dateistream ist nicht mehr "good", nachdem ein Fehler passiert, schließlich kann das Objekt nicht in die Zukunft gucken. Das Ende zu erreichen ist kein Fehler. Über das Ende hinweg lesen ist ein Fehler. Leider sieht man sehr oft Schleifen der Art:
while (datei.good()) // oder noch schlimmer, da es nur auf Dateiende prüft: while(!datei.eof()) { lese(datei, daten); benutze(daten); }Dies ist natürlich falsch, da man einen Lesefehler erst mitbekommt, wenn man die falschen Daten verarbeitet hat. Wenn dir das jemand so zeigt, ist das ein sicheres Zeichen, dass du von dieser Person lieber nichts über Programmierung lernen solltest. Dein Buch gehört anscheinend auch dazu.
Dies gilt übrigens genau so in C, Java und vielen ähnlichen Sprachen (wird dort genau so oft falsch gemacht), also kann sich niemand raus reden, dass C++ hier eine Ausnahme wäre. C++ erlaubt bloß die schicke Schreibweise:
while(lese(datei, daten)) benutze(daten);Die man häufig so oder ähnlich verwendet.
-
Ahh ja. Ok
Ich habe es gecheckt.
Danke