Wann setzt 'ifstream :: readsome' 'eofbit'?

9

Dieser Code wird für immer wiederholt:

%Vor%

Dies liegt daran, dass readsome niemals eofbit setzt.

cplusplus.com sagt:

  

Fehler werden durch Ändern der internen Zustandsflags signalisiert:

     

eofbit Der get-Zeiger befindet sich am Ende der internen Eingabe des Stream-Puffers   Wenn die Funktion aufgerufen wird, bedeutet dies, dass keine Positionen vorhanden sind   Lesen Sie den internen Puffer (der das Ende der Eingabe sein kann oder nicht)   Sequenz). Dies geschieht, wenn rdbuf()->in_avail() -1 vor dem zurückgibt   erstes Zeichen wird extrahiert.

     

failbit Der Stream befand sich am Ende der Zeichenquelle vor dem   Funktion wurde aufgerufen.

     

badbit Ein anderer Fehler ist aufgetreten.

Fast derselbe Standard lautet:

  

[C++11: 27.7.2.3]: streamsize readsome(char_type* s, streamsize n);

     

32. Effekte: Benutzt sich als unformatierte Eingabefunktion (wie in   27.7.2.3, Absatz 1). Nach dem Erstellen eines Sentry-Objekts, wenn !good() aufruft    setstate(failbit) , die eine Ausnahme auslösen und zurückgeben kann. Ansonsten Extrakte   Zeichen und speichert sie in aufeinanderfolgenden Orten eines Arrays, deren erste   Element wird mit s bezeichnet. Wenn rdbuf()->in_avail() == -1 , Aufrufe    setstate(eofbit) (die ios_base::failure (27.5.5.4) auslösen kann) und Extrakte   keine Zeichen;

     
  • Wenn rdbuf()->in_avail() == 0 , extrahiert keine Zeichen
  •   
  • Wenn rdbuf()->in_avail() > 0 , Extrakte min(rdbuf()->in_avail(),n)) .
  •   

33. Rückgabe: Die Anzahl der extrahierten Zeichen.

Dass die Bedingung in_avail() == 0 eine Nicht-Operation ist, bedeutet, dass ifstream::readsome selbst keine Operation ist, wenn der Strompuffer leer ist, aber die Bedingung in_avail() == -1 bedeutet, dass gesetzt wird eofbit , wenn eine andere Operation zu in_avail() == -1 geführt hat.

Dies scheint eine Inkonsistenz zu sein, trotz der "etwas" Natur von readsome .

Was also sind die Semantiken von readsome und eof ? Habe ich sie richtig interpretiert? Sind sie ein Beispiel für schlechtes Design in der Stream-Bibliothek?

(Gestohlen vom [IMO] ungültigen libstdc ++ Fehler 52169 .)

    
Lightness Races in Orbit 08.02.2012, 10:52
quelle

3 Antworten

4

Ich denke, dies ist ein Anpassungspunkt, der von den Standard-Stream-Implementierungen nicht wirklich verwendet wird.

in_avail() gibt die Anzahl der Zeichen zurück, die im internen Puffer angezeigt werden, falls vorhanden. Andernfalls ruft es showmanyc() auf, um zu ermitteln, ob Zeichen bekanntermaßen an anderer Stelle verfügbar sind, sodass eine Pufferfüllanforderung garantiert erfolgreich ist.

Umgekehrt gibt showmanyc() die Anzahl der Zeichen zurück, die es kennt, falls vorhanden, oder -1, wenn es weiß , dass ein Lesen fehlschlägt, oder 0, wenn es kein a hat Hinweis.

Die Standardimplementierung ( basic_streambuf ) gibt immer 0 zurück, also erhalten Sie, wenn Sie einen Stream mit einem anderen streambuf haben, der showmanyc überschreibt.

Ihre Schleife ist im Wesentlichen wie viele Zeichen gelesen-wie-Sie-wissen-ist-sicher, und sie bleibt stecken, wenn das Null ist (was "nicht sicher" bedeutet).

    
Bo Persson 15.02.2012, 17:06
quelle
1

Wenn kein Zeichen verfügbar ist (d. h. gptr() == egptr() für std:streambuf ), wird die virtuelle Memberfunktion showhowmanyc() aufgerufen. Ich könnte eine Implementierung von showmanyc() haben, die einen Fehlercode zurückgibt. Warum das nützlich ist, ist eine andere Frage. Dies könnte jedoch eof() festlegen. Natürlich soll in_avail() nicht fehlschlagen und nicht blockieren und nur die bekannten Zeichen zurückgeben, die verfügbar sind. Das heißt, die Schleife, die Sie oben haben, ist im Wesentlichen garantiert eine Endlosschleife, es sei denn, Sie haben einen ziemlich ungeraden Stream-Puffer.

    
Dietmar Kühl 08.02.2012 11:13
quelle
0

Ich denke nicht, dass readsome () für das gedacht ist, was Sie versuchen (aus einer Datei auf der Festplatte lesen) ... von cplusplus.com:

  

Die Funktion soll verwendet werden, um Binärdaten von bestimmten zu lesen   Arten von asynchronen Quellen, die auf mehr Zeichen warten können, da   Es hört auf zu lesen, wenn der lokale Puffer erschöpft ist, wodurch Potential vermieden wird   unerwartete Verzögerungen.

Es klingt also so, als ob readsome () für Streams von einem Netzwerk-Socket oder etwas ähnlichem gedacht ist und Sie wahrscheinlich nur read () verwenden wollen.

    
bdow 20.02.2012 23:06
quelle

Tags und Links