C++ istream EOF 不保证failbit?

loo*_*oop 0 c++ eof

我在 Stack Overflow 上阅读了一个问题,其中file设置了 istream 的 eofbit但未设置 failbit。在这种情况下,file 为真,file.eof() 为真,但 file.good() 为假。例如,文件大小正好是一个字节:

ifstream file("one.txt");
assert( file.is_open() );
for( int i = 0; i < 2; ++i )
{
    char chars[255] = {0};
    file.getline(chars, 2);
    //file.read( chars, 2 );

    cout << "file: " << !!file << endl;
    cout << "good: " << file.good() << endl;
    cout << "eof: " << file.eof() << endl;
    cout << "fail: " << file.fail() << endl;
    cout << "bad: " << file.bad() << endl;
    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

file: 1
good: 0
eof: 1
fail: 0
bad: 0

file: 0
good: 0
eof: 1
fail: 1
bad: 0
Run Code Online (Sandbox Code Playgroud)

如果我注释掉 getline() 并使用 read() 代替,我会得到:

file: 0
good: 0
eof: 1
fail: 1
bad: 0

file: 0
good: 0
eof: 1
fail: 1
bad: 0
Run Code Online (Sandbox Code Playgroud)

在这两种情况下,我都在循环的第一次迭代中读取文件末尾。为什么一个 EOF 失败而一个没有?另一个线程中的答案是“每当您遇到文件末尾而不尝试读取它的末尾时”。读到后面了吗?这意味着什么?

ric*_*ici 5

eofbit由设置getline方法,如果它停止读取,因为它撞击流(文件)的端部,而不是通过查找分隔符。getline没有设置failbit在这种情况下,因为它没有失败,这是合乎逻辑的:它读取一些数据。

一旦eofbit设置了 ,对该流的下一个读取操作将设置failbit,因为在几乎每个输入操作开始时调用的内部哨兵函数将设置failbitif eofbit

通常,eofbit“表示输入操作到达输入序列的末尾”,而failbit“表示输入操作未能读取预期的字符”(两个引号均来自 C++ 标准,第[ios.types]27.5.3.1节,表124,在我的最新草稿中。)如getline示例所示,输入操作很可能读取输入序列的末尾,同时仍在读取某些内容。

另一种不太正式的——因此可能不正确的——看待这个的方式是,eofbit如果读取操作到达文件末尾,则failbit设置,而如果读取操作无法读取它的最小字符数,则设置必需的。将2在调用getlineread意味着不同的事情; in getline,是输入操作的最大字符数(最小为1);在 的情况下read,它是精确的字符数。