2013-02-11 13 views
11

Intuitiv, aus der C++ - Spezifikation, sieht es so aus, als ob istream::putback(c) immer den Eingabepuffer so anordnen sollte, dass der nächste Aufruf an istream::peek() das Zeichen c lesen sollte. Ist das nicht korrekt? Ich frage, weil die neueste Version von libC++, die mit Xcode 4.6 ausgeliefert wird, dieses Verhalten anscheinend nicht in allen Fällen erzwingt - insbesondere wenn das letzte Zeichen am EOF ist. Das gleiche gilt, wenn Sie unget() anstelle von putback(c) verwenden.Sollte istream :: peek() nicht immer zurückgeben, was Sie gerade putback()?

Ist das Verhalten von libC++ korrekt oder ist es meine Intuition, wie putback()/unget() korrekt funktionieren sollte?

Betrachten Sie diesen Beispielcode, der mit libstdC++ funktioniert, aber nicht mit libC++ (die Assertion schlägt fehl).

#include <sstream> 
#include <cassert> 

int main(int argc, const char * argv[]) 
{ 
    std::istringstream in("[Test]"); 

    while(in) 
    { 
     int c = in.get(); 
     if(c == ']') 
     { 
      in.putback(c); 
      assert(in.peek() == c); // Fails with libc++. Succeeds with libstdc++. 
      break; 
     } 
    } 

    return 0; 
} 
+2

Werden 'eofbit',' failbit', 'badbit' nach dem' putback (c) 'gesetzt? (Als Referenz: Mit libstdC++ 4.7 ist keiner davon gesetzt, der Stream ist 'gut()'.) – us2012

+0

+1 zu beiden Antworten. Sieht aus wie ein Fehler in libC++, der in r162608 behoben wurde. –

Antwort

6

Es hat tatsächlich eine Änderung der putback Funktion in C++ 11:

§27.7.2.3/34

basic_istream<charT,traits>& putback(char_type c);

Effekte: Verhält sich als unformatierte Eingangs Funktion (wie in 27.7.2.3, Absatz 1 beschrieben), außer dass die Funktion zuerst eofbit löscht. ...

Wo die zweite Hälfte des Satzes in C++ 03 nicht existierte.

Es hängt also davon ab, ob die Compiler diese Änderung vollständig implementiert haben oder ob Sie die erforderlichen Optionen verwenden (-std=C++11?).

4

Bo Persson ist korrekt über die Standards. Sie verwenden wahrscheinlich eine ältere Version von libC++ (Ihr Problem liegt im LLVM-Bugtracker, siehe unten).

--- istream  (revision 162607) 
+++ istream  (revision 162608) 
@@ -1263,6 +1263,7 @@ 
    try 
    { 
#endif // _LIBCPP_NO_EXCEPTIONS 
+  this->clear(this->rdstate() & ~ios_base::eofbit); 
     sentry __sen(*this, true); 
     if (__sen) 
     { 

Das Protokoll über die Änderung:

Die Veränderung der Revision 162108 eingeführt wurde

$ svn log -r 162608

--------- -------------------------------------------------- ------------- r162608 | hhinnant | 2012-08-25 00:03:03 +0200 (Sa, 25. Aug 2012) | 1 Zeile

Haben basic_istream seekg, Putback und Unget erste klare eofbit. Fixes http://llvm.org/bugs/show_bug.cgi?id=13089.

Verwandte Themen