Das folgende (Spielzeug-) Programm gibt verschiedene Dinge zurück, wenn es mit libstdc ++ und libc ++ verknüpft wird. Ist das ein Fehler in libc ++ oder verstehe ich nicht, wie istream () funktioniert? Ich habe versucht, es mit g ++ auf Linux und Mac OS X und Mac OS X, mit und ohne -std = C ++ 0 x. Es war mein Eindruck, dass eof () erst dann wahr zurückgibt, wenn ein Versuch (durch get () oder etwas anderes) fehlschlägt. So verhält sich libstdc ++, verhält sich aber nicht wie libc ++.
%Vor%Dies war ein libc ++ Bug und wurde behoben, wie Cubbi bemerkte. Mein Fehler. Details sind hier:
EDIT : Dies lag an der Art und Weise, wie ältere Versionen von libc ++ den C ++ - Standard interpretierten. Die Interpretation wurde in der LWG-Ausgabe 2036 diskutiert, es wurde entschieden falsch sein und libc ++ wurde geändert.
Aktuelle libc ++ liefert die gleichen Ergebnisse wie libstdc ++.
alte Antwort:
Ihr Verständnis ist richtig.
istream::get()
macht Folgendes:
good()
auf und setzt failbit
, wenn es false zurückgibt (dies fügt ein Failbit zu einem Stream hinzu, der ein anderes Bit gesetzt hat), ( §27.7.2.1.2[istream::sentry]/2
) good()
zu diesem Zeitpunkt false ist, wird eof zurückgegeben und nichts weiter ausgeführt. rdbuf()->sbumpc()
oder rdbuf()->sgetc()
( §27.7.2.1[istream]/2
) sbumpc()
oder sgetc()
eof zurückgibt, wird eofbit
festgelegt. ( §27.7.2.1[istream]/3
) und failbit
( §27.7.2.2.3[istream.unformatted]/4
) §27.7.2.2.3[istream.unformatted]/1
) gesetzt und erneut ausgeführt, falls erlaubt. (Kapitel zitiert aus C ++ 11, aber C ++ 03 hat alle die gleichen Regeln, unter §27.6. *)
Sehen wir uns nun die Implementierungen an:
libc ++ (aktuelle svn-Version) definiert den relevanten Teil von get () als
%Vor%libstdc ++ (wie mit gcc 4.6.2 ausgeliefert) definiert den gleichen Teil wie
%Vor% Wie Sie sehen, rufen beide Bibliotheken sbumpc()
auf und setzen eofbit genau dann, wenn sbumpc () eof zurückgibt.
Ihr Testfall erzeugt die gleiche Ausgabe für mich mit den neuesten Versionen beider Bibliotheken.
Der Wert von s.eof()
ist im zweiten Aufruf nicht angegeben - das kann sein
wahr oder falsch, und es könnte nicht einmal konsistent sein. Alles was du sagen kannst ist
Wenn s.eof()
wahr zurückgibt, werden alle zukünftigen Eingaben fehlschlagen (aber wenn es
gibt false zurück, es gibt keine Garantie, dass zukünftige Eingaben erfolgreich sein werden).
Nach dem Fehler ( s.fail()
), wenn s.eof()
wahr zurückgibt, ist es wahrscheinlich (aber
nicht 100% sicher), dass der Fehler auf das Ende der Datei zurückzuführen war. Es ist es wert
unter Berücksichtigung des folgenden Szenarios:
Auf meinem Rechner sind beide Zeilen "TT"
, trotz der Tatsache, dass der erste
fehlgeschlagen, weil keine Daten vorhanden waren (Ende der Datei), der zweite, weil der
Gleitkommawert wurde falsch formatiert.
eofbit ist gesetzt, wenn es eine Operation gibt, die versucht, über das Ende der Datei hinaus zu lesen, die Operation kann nicht fehlschlagen (wenn Sie eine Ganzzahl lesen und es kein Ende der Zeile hinter der Ganzzahl gibt, erwarte ich, dass efbit gesetzt wird aber das Lesen der ganzen Zahl zum Erfolg). I.E. Ich bekomme und erwarte FT für
%Vor%Hier erwarte ich nicht, dass istream :: get versuchen soll, nach dem zurückgegebenen Zeichen zu lesen (dh ich erwarte nicht, dass es so lange hängt, bis ich die nächste Zeile lese, wenn ich a \ n damit lese), so scheint libstd ++ in der Tat, zumindest in einem QOI POV.
Die Standardbeschreibung für istream :: get sagt nur "extrahiert ein Zeichen c, falls vorhanden" ohne zu beschreiben, wie und so scheint es das Verhalten von libc ++ nicht zu verhindern.