是否存在最后一个操作成功但 istream/ostream 变为 fail() 的情况?

Are there cases where the last operation succeeds but the istream/ostream goes fail()?

提问人:CPPL 提问时间:3/26/2022 更新时间:3/26/2022 访问量:58

问:

我是C++的新学习者。在我的理解中,指示对 / 的最后一次操作是否成功。例如,让我们打开一些有效的文件:fail()istreamostreamifsifstream

string s;
while (ifs >> s) {
    // 1. assume the reading was taken successfully
    //    and do something according to that
}
// 2. assume the reading was unsuccessful
//    and do something according to that

请问,在某些(角落)情况下,我们是否有可能在实际成功读取时到达?2.

如果是这样,我们的所作所为可能会有问题。例如,如果我们设置了 ,那么我们将(可能)假设 在 处为空。2.ifs.exceptions(ifs.exceptions() | ios_base::badbit);ifs2.


当我使用Stroustrup的书《编程:使用C++的原理与实践》(第2版)自学C++时,我提出了这个问题。在本书的第 11.7 章中,作者设计了一个类,该类采用 as ,处理从 中提取的数据,然后将处理后的数据放入称为 waiting to be input 到 程序 中的数据成员中。作者设计的方法如下(第 404 页):Punct_streamistreamsourcesourceistringstreambufferoperator bool()

Punct_stream::operator bool()
{
    return !(source.fail() || source.bad()) && buffer.good();
}

首先,我认为应该等同于只是检查,因为同时考虑了 和 ,而检查等同于检查。!(source.fail() || source.bad())sourcefail()failbitbadbitsource!fail()

与我的问题更相关的是,通过这种设计,将首先检查是否处于错误状态,如果是,它甚至不会查看 .但是,只要 中有字符,就可以将数据从 a 读入 a。因此,如果 不为空并且 是 ,那么从 中读取 实际上会成功,而对条件的检查将是 。operator bool()sourcebufferPunct_streamstringbufferbuffersourcefail()Punct_streamstringPunct_streamfalse

我想知道标准库的实现是否可能以某种类似的方式运行,例如在某些情况下,读取实际上已成功进行,但条件被评估为?istreamfalse

C++ IO IO流

评论


答:

0赞 Chris Dodd 3/26/2022 #1

所有 iostream 输入函数都从创建一个对象开始,该对象检查流的状态。如果状态不是(即 或 中的任何一个),则哨兵将设置 和 返回 false,这将导致输入函数立即返回,而不读取任何内容,不修改(甚至检查)streambuffer,也不将任何内容写入输入函数的目标。sentrygoodgoodbadbiteoffailbitfailbit

因此,根据定义,如果 中的流测试是 false,则它之前一定是 false 或 eof(并且没有将任何内容读入字符串),或者它无法将任何内容读入字符串,并将状态设置为 false。无论哪种情况,都不会将任何内容读入字符串中。whiles