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, wennrdbuf()->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()
aufruftsetstate(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 mits
bezeichnet. Wennrdbuf()->in_avail() == -1
, Aufrufesetstate(eofbit)
(dieios_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
, Extraktemin(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 .)
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).
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.
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.