Warum setzt std :: ios_base :: ignore () das EOF-Bit?

8

Wenn ich alle Daten aus einem Stream lese, aber nicht versuche, über das Ende hinaus zu lesen, wird der EOF des Streams nicht gesetzt. So funktionieren C ++ - Streams, oder? Es ist der Grund, warum das funktioniert:

%Vor%

Wenn jedoch anstelle von read() ing Daten I ignore() it, wird EOF gesetzt:

%Vor%

Dies ist auf GCC 4.8 und GCC trunk (Coliru).

Es hat auch den unglücklichen Nebeneffekt, tellg() return -1 zu machen (weil das tellg() tut), was für das, was ich mache, ärgerlich ist.

Ist das Standard-Mandat? Wenn ja, welche Passage und warum? Warum versucht ignore() mehr zu lesen, als ich es ihm gesagt habe?

Ich kann auf der cppreference-Seite ignore() keinen Grund für dieses Verhalten finden. Ich kann wahrscheinlich .seekg(6, std::ios::cur) stattdessen, oder? Aber ich würde trotzdem gerne wissen, was vor sich geht.

    
Lightness Races in Orbit 28.10.2016, 15:11
quelle

1 Antwort

4

Ich denke, das ist ein libstdc ++ Bug ( 42875 , h/t NathanOliver). Die Anforderungen für ignore() in [istream.unformatted] sind:

  

Zeichen werden bis zu jedem Zeichen extrahiert   Folgendes passiert:
  - n != numeric_limits<streamsize>::max() (18.3.2) und n Zeichen wurden bisher extrahiert   - Das Ende der Datei tritt in der Eingabefolge auf (in diesem Fall ruft die Funktion setstate(eofbit) ,   was kann ios_base::failure (27.5.5.4)) werfen;
  - traits::eq_int_type(traits::to_int_type(c), delim) für das nächste verfügbare Eingabezeichen   c (in diesem Fall wird c extrahiert).
Bemerkungen: Die letzte Bedingung wird niemals auftreten, wenn traits::eq_int_type(delim, traits::eof()) .

Also haben wir zwei Bedingungen (die letzte wird ignoriert) - wir lesen entweder n Zeichen, oder irgendwann haben wir das Ende der Datei erreicht, in diesem Fall setzen wir eofbit . Aber wir können in diesem Fall n -Zeichen aus dem Stream lesen (es gibt tatsächlich 6 Zeichen in Ihrem Stream), so dass wir das Ende der Datei nicht in der Eingabesequenz treffen.

In libc ++ ist eof() nicht gesetzt und tellg() gibt 6 zurück.

    
Barry 28.10.2016, 15:27
quelle

Tags und Links