2013-01-24 8 views
5

Nicolai Josuttis ở trang 547 của cuốn sách của ông "The C thư viện chuẩn ++" nói như sau liên quan đến mã bên dưới:Nicolai Josuttis nói trong cuốn sách của mình rằng chức năng thành viên mở không xóa các cờ trạng thái. Đó không phải là những gì tôi tìm thấy trong VS2010. Đây có phải là vấn đề về MS không?

Note that after the processing of a file, clear() must be called to clear the state flags that are set at end-of-file. This is required because the stream object is used for multiple files. The member function open() does not clear the state flags. open() never clears any state flags. Thus, if a stream was not in a good state, after closing and reopening it you still have to call clear() to get to a good state. This is also the case, if you open a different file.

// header files for file I/O 
#include <fstream> 
#include <iostream> 
using namespace std; 
/* for all file names passed as command-line arguments 
* - open, print contents, and close file 
*/ 
int main (int argc, char* argv[]) 
{ 
    ifstream file; 
    // for all command-line arguments 
    for (int i=1; i<argc; ++i) { 
     // open file 
     file.open(argv[i]); 
     // write file contents to cout 
     char c; 
     while (file.get(c)) { 
      cout.put(c); 
     } 
     // clear eofbit and failbit set due to end-of-file 
     file.clear(); 
     // close file 
     file.close(); 
    } 
} 

Mã của tôi dưới đây hoạt động mà không một vấn đề trong VS2010. Lưu ý rằng sau khi tệp "data.txt" được tạo, nó được đọc hai lần mà không xóa các cờ luồng đầu vào.

#include <iostream> 
#include <fstream> 
#include <string> 

int main() 
{ 
    // Create file "data.txt" for writing, write 4 lines into the file and close the file. 

    std::ofstream out("data.txt"); 
    out << "Line 1" << '\n' << "Line 2" << '\n' << "Line 3" << '\n' << "Line 4" << '\n'; 
    out.close(); 

    // Open the file "data.txt" for reading and write file contents to cout 

    std::ifstream in("data.txt"); 
    std::string s; 
    while(std::getline(in, s)) std::cout << s << '\n'; 
    std::cout << '\n'; 
    std::cout << std::boolalpha << "ifstream.eof() before close - " << in.eof() << '\n'; 

    // Close the file without clearing its flags 

    in.close(); 
    std::cout << std::boolalpha << "ifstream.eof() after close - " << in.eof() << '\n'; 

    // Open the file "data.txt" again for reading 

    in.open("data.txt"); 
    std::cout << std::boolalpha << "ifstream.good() after open - " << in.good() << '\n'; 
    std::cout << '\n'; 

    // Read and print the file contents 

    while(std::getline(in, s)) std::cout << s << '\n'; 
    std::cout << '\n'; 
} 

Ouput

enter image description here

Trả lời

4

đó đã được thay đổi cho C++ 11. Quy tắc C++ 98 (được mô tả chính xác bởi Josuttis) rõ ràng là sai, vì vậy tôi sẽ không ngạc nhiên nếu việc triển khai không tôn trọng nó.

+0

Một số điểm dữ liệu: đối với MSVC, hành vi này là mới với VC++ 2010; 2008 và trước không xóa cờ luồng trên 'open()'. GCC 4.6.1 trên Linux hoạt động giống như VC++ 2010 (nghĩa là, ngữ nghĩa C++ 11 ngay cả khi bạn chỉ định '--std = C++ 98'). –