【问题标题】:Successfully open but not good?成功打开但不好?
【发布时间】:2012-09-19 12:51:59
【问题描述】:

在C++中,有没有std::ifstream open()可以成功,而std::ifstream good()可以为假的情况?

编辑:用 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;
}

将为空文件返回:1, 0, 0, 0,这意味着 good = TRUEeof = fail = bad = FALSE。正常吗?

【问题讨论】:

    标签: c++ file stream


    【解决方案1】:

    在验证标准中的实际文本后,我认为open之后不允许设置eofbit:如果实际打开抛出异常,则可以设置badbit(我认为-标准并没有真正说明在这种情况下应该发生什么); failbit 应该设置如果打开失败,或者如果打开后的搜索(如果设置了ate)失败;但似乎没有任何情况可以设置eofbit

    在这种情况下,调用std::istream::good() 并不是一个好的解决方案。 (知道 OP 试图实现什么会很有趣。无论如何,调用 std::istream::good() 可能不是正确的解决方案。)

    如果std::ifstream::good() 返回false,则下一次输入将失败。 如果它返回true,它什么也不告诉你:下一个输入可能成功, 但它也可能失败。

    【讨论】:

    • +1 在您尝试读取并且读取失败之前,实现实际上可能不会测试文件。
    • @DavidRodríguez-dribeas 通常,在输入失败之前测试eofbit 是没有意义的。而std::ifstream::good() 测试eofbit(除了其他状态位)这一事实使它几乎毫无价值。
    • 我认为使用good 的提问者没有任何伤害 是吗?只是因为没有设置eofbit,你不妨像平常一样测试流的真实性。我认为做一些毫无意义的异常行为会损害可读性,就像你说的那样,几乎任何使用good 都是毫无意义的异常......
    • @SteveJessop 在这种特殊情况下,good 实际上是可用的,因为可以保证eofbit 是假的。但是它发送给读者的消息(你不知道 iostreams)仍然存在。任何时候你可以使用“规范”解决方案,你都应该这样做,因为做其他事情会发送一个消息,要么你不知道情况,要么它有一些特别之处,这意味着不能使用规范解决方案。
    【解决方案2】:

    如果文件为空,将触发 eofbit,但文件仍将打开,所以是的。

    【讨论】:

    • 我的理解是只有在操作尝试读取文件末尾之后才会设置 eofbit。这不正确吗?
    • @templatetypedef 我不确定。可以肯定的是,如果文件为空,则不需要实现设置eofbit,但我不确定是否不允许这样做。如果设置了eofbit,则表示下一次输入将失败,因为没有数据。 (如果eofbit 没有设置,则没有任何意义。)
    • 根据我对标准的解读,这是不正确的。当底层文件缓冲区的open() 成功时,文件流中的所有状态位都会被清除。如果文件缓冲区open() 失败,则状态设置为failbit。无论哪种方式,eofbit 在调用文件流open() 后都会被清除。
    • 我刚刚测试过它,使用 g++ 4.7.1,如果你打开一个空文件:good = TRUEeof = fail = bad = FALSE。正常吗?
    【解决方案3】:

    ifstream::open 返回 void,所以要小心你所说的“成功”是什么意思。

    标准规定basic_ifstream::open (27.9.1.9):

    效果:调用 rdbuf()->open(s, mode | ios_base::in)。如果那个函数 不返回空指针调用 clear(),否则调用 setstate(failbit)(可能会抛出 ios_base::failure)

    因此,如果对 filebuf 的 open 调用返回一个表示成功的值,则 ifstream::open 会清除所有错误位,因此 good() 必然返回 true。

    如果对 filebuf 的 open 调用返回一个指示失败的值,那么 ifstream::open 仍然可以返回而不会引发异常。此行为可能与“成功”混淆,但在这种情况下,good() 返回 false,因为设置了失败位。

    我并不完全清楚为什么这会设置故障位而不是坏位,但我不认为我缺乏理解会妨碍报告事实:-)

    【讨论】:

      猜你喜欢
      • 2018-07-11
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-08
      • 1970-01-01
      • 2016-11-05
      相关资源
      最近更新 更多