【问题标题】:ifstream: check if opened successfullyifstream: 检查是否打开成功
【发布时间】:2011-05-11 13:06:09
【问题描述】:

一位同事刚刚告诉我这段代码:

std::ifstream stream(filename.c_str());
if (!stream)
{
    throw std::runtime_error("..");
}

会错的。他说如果打开成功,ifstream 的计算结果为 0。我的代码有效,但我想找到文档,但没有看到它说明如何检查打开是否成功。可以指点一下吗?

【问题讨论】:

    标签: c++ iostream


    【解决方案1】:

    operator! is overloaded for std::ifstream,所以你可以这样做。

    不过,在我看来,这是对运算符重载的可怕滥用(由标准委员会提出)。如果您只执行if (stream.fail()),您正在检查的内容会更加明确。

    【讨论】:

    • 别忘了检查stream.bad()stream.good()stream.fail()stream.is_open()。叹息……
    • 该!重载以检查“失败”和“错误”
    • 这里没有“滥用”。
    • 我实际上认为 fail 比操作符更多模棱两可和/或可能令人困惑,只是因为尽管它的名称它同时检查 failbit 和 badbit。
    • @abhinav:因为它(很大程度上)是一种特殊的雪花 - 这(使用 ! 表示“失败”)不是通用模式,因此 IMO 它降低了易读性。
    【解决方案2】:

    您可以通过使用适当的位掩码调用其ios::exceptions() 函数来使特定流在任何eof/fail/bad 上引发异常。因此,您可以将上面最初问题中的示例重写为:

    std::ifstream stream;
    stream.exceptions(std::ios::failbit | std::ios::badbit);
    stream.open(filename.c_str());
    

    当failbit 或badbit 被设置时,这里的流将抛出异常。例如,如果ifstream::open() 失败,它将设置失败位并抛出异常。当然,如果这些位中的任何一个在流上设置,这将在稍后引发异常,因此此重写与初始示例不完全相同。你可以打电话

    stream.exceptions(std::ios::goodbit);
    

    取消流中的所有异常并返回检查错误。

    【讨论】:

      【解决方案3】:

      您也可以使用is_open() 来检查它是否有效,但是!是允许的(它不是检查零,它是一个特殊的overload of !

      编辑:
      只是出于兴趣 - 为什么不抛出异常?
      是否只是在异常之前引入了流
      还是我们进入了旧的 C++ 事物 - 这只是一个错误,不足以成为异常。

      【讨论】:

      • 我想知道 20 年以来,存在一个不成功的 ifstream 对象的需要是什么......可能在另外 20 年内,这个问题可能会得到解决(通过引入另一个构造函数额外的 please_throw() 参数?)。希望到这个时候,错误的原因将包含在异常对象中。
      【解决方案4】:

      你的同事错了。也许他忘记了你不是在写 C。

      代码是正确的。 正是你应该如何检查流状态。

      【讨论】:

        猜你喜欢
        • 2011-09-09
        • 2013-08-26
        • 1970-01-01
        • 2011-03-13
        • 1970-01-01
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多