2011-10-21 20 views
6

Có thể sử dụng getline() để đọc tệp hợp lệ mà không cần thiết lập failbit không? Tôi muốn sử dụng failbit để ngoại lệ được tạo nếu tệp đầu vào không thể đọc được.Sử dụng getline() mà không cài đặt failbit

Mã sau luôn luôn xuất ra basic_ios::clear làm dòng cuối cùng - ngay cả khi đầu vào hợp lệ được chỉ định.

test.cc:

#include <iostream> 
#include <string> 
#include <fstream> 
using namespace std; 

int main(int argc, char* argv[]) 
{ 
    ifstream inf; 
    string line; 

    inf.exceptions(ifstream::failbit); 
    try { 
     inf.open(argv[1]); 
     while(getline(inf,line)) 
      cout << line << endl; 
     inf.close(); 
    } catch(ifstream::failure e) { 
     cout << e.what() << endl; 
    } 
} 

INPUT.TXT:

the first line 
the second line 
the last line 

kết quả:

$ ./a.out input.txt 
the first line 
the second line 
the last line 
basic_ios::clear 
+0

Khi nào bạn mong đợi failbit được nâng lên khi sử dụng getline()? – selalerer

+0

Nếu tệp không tồn tại. ví dụ: './a.out nosuchfile.txt' – Jeremiah

+0

Để biết rằng bạn có thể kiểm tra is_open() sau khi bạn mở tệp. – selalerer

Trả lời

6

Bạn không thể. Tiêu chuẩn nói về getline:

Nếu chức năng chiết xuất không có ký tự, nó gọi is.setstate(ios_base::failbit) có thể ném ios_base::failure (27.5.5.4).

Nếu tệp của bạn kết thúc bằng một dòng trống, tức là ký tự cuối cùng là '\ n', thì cuộc gọi cuối cùng để getline không đọc ký tự và không thành công. Thật vậy, làm thế nào bạn muốn vòng lặp để chấm dứt nếu nó sẽ không đặt failbit? Điều kiện của while sẽ luôn đúng và sẽ chạy mãi mãi.

Tôi nghĩ rằng bạn hiểu sai ý nghĩa của failbit. Nó không không có nghĩa là không thể đọc tệp. Nó được sử dụng như một lá cờ mà hoạt động cuối cùng đã thành công. Để chỉ ra một lỗi mức thấp, badbit được sử dụng, nhưng nó có rất ít sử dụng cho các luồng tập tin chuẩn. failbit và eofbit thường không nên được hiểu là các tình huống ngoại lệ. badbit mặt khác nên, và tôi sẽ lập luận rằng fstream :: open nên đã thiết lập badbit thay vì failbit.

Dù sao, các mã trên nên được viết như sau:

try { 
    ifstream inf(argv[1]); 
    if(!inf) throw SomeError("Cannot open file", argv[1]); 
    string line; 
    while(getline(inf,line)) 
     cout << line << endl; 
    inf.close(); 
} catch(const std::exception& e) { 
    cout << e.what() << endl; 
} 
+0

Cảm ơn bạn đã giải thích các giới hạn 'failbit'. Triển khai của bạn hoạt động. – Jeremiah