2013-02-11 10 views
11

Trực quan, đánh giá từ thông số C++, có vẻ như tôi istream::putback(c) nên luôn sắp xếp bộ đệm đầu vào sao cho lệnh gọi tiếp theo là istream::peek() phải đọc ký tự c. Điều này có đúng không? Tôi hỏi vì phiên bản libC++ mới nhất với Xcode 4.6 dường như không thực thi hành vi này trong mọi trường hợp - đặc biệt khi ký tự cuối cùng ở EOF. Điều này cũng đúng nếu bạn sử dụng unget() thay vì putback(c).Không nên istream :: peek() luôn trả về những gì bạn vừa bỏ lại()?

Hành vi của libC++ có đúng không, hoặc trực giác của tôi về cách putback()/unget() có hoạt động chính xác không?

Hãy xem xét mã ví dụ này, hoạt động với libstdC++ nhưng không phải với libC++ (xác nhận không thành công).

#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

Có bất kỳ «eofbit',' failbit', 'badbit' nào được đặt sau' putback (c) 'không? (Để tham khảo: Với libstdC++ 4.7, không có gì trong số đó được thiết lập, luồng là 'good()'.) – us2012

+0

+1 cho cả hai câu trả lời. Có vẻ như một lỗi trong libC++ đã được sửa trong r162608. –

Trả lời

6

Có thực sự là một sự thay đổi đến putback hàm trong C++ 11:

§27.7.2.3/34

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

Effects: Hoạt động như một đầu vào chưa định dạng chức năng (như được mô tả trong 27.7.2.3, đoạn 1), ngoại trừ chức năng đầu tiên xóa eofbit. ...

Trường hợp phần thứ hai của câu không tồn tại trong C++ 03.

Vì vậy, nó có thể phụ thuộc vào việc các trình biên dịch có thực hiện đầy đủ thay đổi này hay không hoặc nếu bạn sử dụng các tùy chọn bắt buộc (-std=C++11?).

4

Bo Persson đúng về tiêu chuẩn. Bạn có thể đang sử dụng phiên bản cũ hơn của libC++ (vấn đề của bạn nằm trong trình gỡ lỗi LLVM, xem bên dưới).

Sự thay đổi đã được giới thiệu trong phiên bản 162.108:

--- 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) 
     { 

Nhật ký liên quan đến sự thay đổi:

$ svn log -r 162608

--------- -------------------------------------------------- ------------- r162608 | hhinnant | 2012-08-25 00:03:03 +0200 (Thứ bảy, 25 tháng 8 năm 2012) | 1 dòng

Có basic_istream seekg, putback và unget eofbit rõ ràng đầu tiên. Sửa chữa http://llvm.org/bugs/show_bug.cgi?id=13089.