Warum wird iostream :: eof in einer Schleifenbedingung als falsch angesehen?
Ich habe gerade einen Kommentar in diese Antwort sagen, dass mit iostream::eof
in einer Schleife, Bedingung ist "nahezu sicher falsch". Ich verwende in der Regel so etwas wie while(cin>>n)
- ich glaube, das implizit prüft EOF, warum ist die überprüfung für eof explizit mit iostream::eof
falsch?
Wie unterscheidet es sich von mit scanf("...",...)!=EOF
in C (was ich oft verwenden, ohne Probleme)?
InformationsquelleAutor der Frage MAK | 2011-04-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Weil
iostream::eof
nur zurücktrue
nach Lesen das Ende des Streams. Es tut nicht darauf hinzuweisen, dass die nächste lese-wird das Ende des Streams.Betrachten Sie diese (und übernehmen dann weiter Lesen, werden am Ende des Streams):
Gegen diese:
Und auf Ihre zweite Frage: Da
ist das gleiche wie
und nicht das gleiche wie
InformationsquelleAutor der Antwort Xeo
Bottom-line-top: Mit der richtigen Handhabung von white-space, das folgende ist, wie
eof
verwendet werden können (und sogar zuverlässiger alsfail()
für die Fehlerprüfung):(Dank Tony D für die Anregung zu markieren die Antwort. Siehe sein Kommentar unten für ein Beispiel, warum das so ist robuster.)
Das wichtigste argument gegen die Verwendung von
eof()
scheint zu sein, fehlt eine wichtige Feinheit, über die Rolle der weißen Raum. Mein Vorschlag ist, dass die überprüfungeof()
explizit ist nicht nur nicht "immer falsch" - das scheint zu einem überwiegenden Meinung in diesen und ähnlichen SO threads --, aber mit der richtigen Handhabung von white-space, sorgt es für eine saubere und zuverlässige Fehlerbehandlung, und ist die immer richtig Lösung (obwohl, nicht unbedingt die tersest).Zusammenfassen, was wird vorgeschlagen, die als die "richtige" Kündigung und lese-Reihenfolge ist folgende:
Den Ausfall aufgrund von lese-Versuch über eof als Abbruchbedingung. Dies bedeutet, dass es keine einfache Möglichkeit, zu unterscheiden zwischen einem erfolgreichen stream-und eine, die wirklich scheitert aus anderen Gründen als der eof. Nehmen Sie die folgenden Ströme:
1 2 3 4 5<eof>
1 2 a 3 4 5<eof>
a<eof>
while(in>>data)
endet mit einem Satzfailbit
für alle drei ein. In der ersten und Dritten,eofbit
ist auch gesetzt. Also vorbei an den loop braucht man sehr hässlich zusätzliche Logik zu unterscheiden, dem richtigen input (1.) durch unsachgemäße (2. und 3.).In der Erwägung, dass die folgenden:
Hier
in.fail()
überprüft, wie lange, wie es ist, etwas zu Lesen, es ist die richtige. Es ist Ziel ist nicht eine bloße while-loop-terminator.So weit so gut, aber was passiert, wenn es Leerzeichen im stream -- was sich anhört wie die großen Bedenken gegen
eof()
als terminator?Brauchen wir nicht zu kapitulieren unsere Fehler-handling; einfach nur Essen, bis die white-space:
std::ws
überspringt alle Potenzial (null oder mehr) Leerzeichen in den Strom während der Einstellung dereofbit
und nicht diefailbit
. Alsoin.fail()
wie erwartet funktioniert, solange es mindestens einen Daten zu Lesen. Wenn alle-leer-streams sind auch in Ordnung, dann die richtige form ist:Zusammenfassung: Eine richtig konstruierte
while(!eof)
ist nicht nur möglich und nicht falsch, sondern es erlaubt, Daten lokalisiert werden, die in Umfang, und liefert eine sauberere Trennung der Fehlerprüfung von business as usual. Dass gesagt wird, diewhile(!fail)
ist unbestritten ein häufiger und knappe Sprache, und kann bevorzugt in einfacher (single-Daten-per-Lesen-Typ-Szenarien).InformationsquelleAutor der Antwort sly
Weil wenn die Programmierer nicht schreiben
while(stream >> n)
Sie könnten schreiben:Hier das problem ist, man kann nicht
some work on n
ohne zuvor zu prüfen, wenn der stream Lesen erfolgreich war, denn wenn es nicht erfolgreich war, Ihresome work on n
würde unerwünschte Ergebnis.Der springende Punkt ist, dass
eofbit
badbit
oderfailbit
gesetzt sind nach dem Versuch zum Lesen aus dem stream. Also, wennstream >> n
ausfällt, danneofbit
badbit
oderfailbit
ist umgehend, so dass Ihr weitere Redewendungen, wenn Sie schreibenwhile (stream >> n)
werden, weil das zurückgegebene Objektstream
konvertiertfalse
wenn es einige Fehler in der Lesung aus dem stream und somit die Schleife beendet. Und es wandelt auftrue
wenn das Lesen erfolgreich war und die Schleife fortgesetzt.InformationsquelleAutor der Antwort Nawaz
Wenn Sie mit der Linie 2 in 3 und Zeile 3 im 2 erhalten Sie
ch
zweimal gedruckt.Also cout vorher Lesen.
InformationsquelleAutor der Antwort Mohammed Younus