2012-09-27 38 views
6

Trong C++, có trường hợp std::ifstream open() có thể thành công hay không, nhưng std::ifstream good() có thể sai không?Mở thành công nhưng không tốt?

EDIT: thử nghiệm với g ++ 4.7.1

#include <iostream> 
#include <fstream> 
int main(int argc, char *argv[]) 
{ 
    std::ifstream filestream("testfile"); 
    std::cout<<filestream.good()<<std::endl; 
    std::cout<<filestream.eof()<<std::endl; 
    std::cout<<filestream.fail()<<std::endl; 
    std::cout<<filestream.bad()<<std::endl; 
    return 0; 
} 

sẽ trở lại: 1, 0, 0, 0 cho một tập tin rỗng có nghĩa good = TRUEeof = fail = bad = FALSE. Nó có bình thường không ?

Trả lời

3

Sau khi kiểm tra các văn bản thực tế trong tiêu chuẩn, tôi không nghĩ rằng eofbit được phép được thiết lập sau khi một open: badbit thể được thiết lập nếu mở thực tế ném một ngoại lệ (tôi nghĩ — tiêu chuẩn không thực sự nói điều gì sẽ xảy ra trong trường hợp này); failbit nên được đặt nếu mở không thành công hoặc nếu tìm kiếm sau khi mở (nếu ate được đặt) không thành công; nhưng dường như không có trường hợp nào có thể đặt eofbit.

Không phải việc gọi std::istream::good() là giải pháp tốt trong trường hợp này. (Thật thú vị khi biết OP đang cố gắng đạt được gì. Dù là gì, gọi số std::istream::good() có lẽ không phải là giải pháp phù hợp.)

Nếu std::ifstream::good() trả về false, đầu vào tiếp theo sẽ thất bại. Nếu nó trả về true, nó sẽ không cho bạn biết gì: đầu vào tiếp theo có thể thành công, nhưng nó cũng có thể không thành công.

+0

+1 việc triển khai thực sự có thể không kiểm tra tệp cho đến khi bạn thử đọc và đọc không thành công. –

+0

@ DavidRodríguez-dribeas Nói chung, nó không có ý nghĩa để kiểm tra 'eofbit' cho đến khi một đầu vào đã thất bại. Và thực tế là 'std :: ifstream :: good()' kiểm tra 'eofbit' (ngoài các bit trạng thái khác) làm cho nó khá vô giá trị. –

+0

Tôi không nghĩ có bất kỳ tác hại * nào trong câu hỏi bằng cách sử dụng 'good' ở đó không? Chỉ vì 'eofbit' không được thiết lập, bạn cũng có thể kiểm tra luồng cho sự thật như bình thường. Tôi cho rằng có khả năng dễ gây hại khi làm điều gì đó vô nghĩa bất thường, và như bạn nói khá nhiều việc sử dụng 'good' là vô nghĩa bất thường ... –

2

Nếu tệp rỗng, eofbit sẽ được kích hoạt nhưng tệp vẫn sẽ mở để có.

+0

hiểu biết của tôi là eofbit đó là chỉ được đặt nếu một thao tác cố gắng đọc qua phần cuối của tệp. Điều đó có đúng không? – templatetypedef

+0

@templatetypedef Tôi không chắc chắn. Chắc chắn rằng việc triển khai không bắt buộc phải đặt 'eofbit' nếu tệp trống, nhưng tôi không chắc rằng nó không được phép. Nếu 'eofbit' được đặt, nó có nghĩa là đầu vào tiếp theo sẽ thất bại vì không có dữ liệu. (Nếu 'eofbit' không được thiết lập, nó không có ý nghĩa gì cả.) –

+1

Điều này là không chính xác cho mỗi bài đọc của tôi về tiêu chuẩn.Tất cả các bit trạng thái trong luồng tệp sẽ bị xóa khi tệp 'open()' của bộ đệm cơ bản thành công. Trạng thái được đặt thành 'failbit' nếu bộ đệm tệp' open() 'không thành công. Dù bằng cách nào, 'eofbit' sẽ rõ ràng sau khi cuộc gọi đến luồng tập tin 'open()'. –

1

ifstream::open trả về khoảng trống, vì vậy hãy cẩn thận chính xác những gì bạn muốn nói bằng cách nói rằng "thành công".

Tiêu chuẩn nói cho basic_ifstream::open (27.9.1.9):

Effects: Gọi rdbuf() -> mở (s, chế độ | ios_base :: in). Nếu đó là chức năng không trả về một con trỏ null gọi rõ ràng(), nếu không gọi setstate (failbit) (có thể ném ios_base :: thất bại)

Vì vậy, nếu cuộc gọi để mở trên filebuf trả về giá trị cho biết thành công, sau đó ifstream::open xóa tất cả các bit lỗi và vì vậy, good() nhất thiết phải trả về giá trị đúng.

Nếu cuộc gọi mở trên filebuf trả về giá trị cho biết lỗi, thì ifstream::open vẫn có thể quay trở lại mà không cần ném ngoại lệ. Hành vi này có thể bị nhầm lẫn với "thành công", nhưng trong trường hợp này, good() trả về false vì giá trị failbit được đặt.

Nó không hoàn toàn rõ ràng với tôi lý do tại sao điều này đặt ra failbit chứ không phải là badbit, nhưng tôi không nghĩ rằng tôi thiếu hiểu biết được trong cách báo cáo các sự kiện :-)

Các vấn đề liên quan