ifstream:检查是否成功打开

Phi*_*ipp 38 c++ iostream

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

std::ifstream stream(filename.c_str());
if (!stream)
{
    throw std::runtime_error("..");
}
Run Code Online (Sandbox Code Playgroud)

会错的.ifstream如果开放成功,他说评估为0.我的代码有效,但我想查找文档,但没有看到它说如何检查开放是否成功.你能指点我吗?

Oli*_*rth 46

operator! 超载std::ifstream,这样你就可以做到这一点.

但在我看来,这是对运营商超载的严重滥用(由标准委员会).如果你这样做,那么你要检查的更明确if (stream.fail()).

  • 的!超载检查'失败'和'坏' (12认同)
  • 不要忘记检查`stream.bad()`,`stream.good()`,`stream.fail()`和`stream.is_open()`.叹... (9认同)
  • 这里没有"滥用". (5认同)
  • 我实际上认为失败是_more_模糊和/或可能比操作员混淆,只是因为它检查failbit和badbit,尽管它的名字. (4认同)
  • 在这一点上可能已经进入了自行车棚领域,但在我看来,“操作符!”对于任何重要的类/结构来说都是非常普遍的意思是“这个对象处于无效状态”。我个人认为这比“.fail()”更清晰,乍一看它是一个动词,让我检查文档以确保确定。 (3认同)
  • @abhinav:因为它(很大程度上)是一种特殊的雪花 - 这个(使用!表示"失败")并不是一种通用模式,所以IMO*会降低*易读性. (2认同)

小智 11

您可以通过使用正确的位掩码调用其ios :: exceptions()函数,使特定流在任何eof/fail/bad上抛出异常.因此,您可以在上面的初始问题中重写示例:

std::ifstream stream;
stream.exceptions(std::ios::failbit | std::ios::badbit);
stream.open(filename.c_str());
Run Code Online (Sandbox Code Playgroud)

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

stream.exceptions(std::ios::goodbit);
Run Code Online (Sandbox Code Playgroud)

取消流上的所有异常并返回检查错误.


Mar*_*ett 10

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

编辑:
只是出于兴趣 - 为什么不抛出异常?
是仅仅在异常之前引入了流,
还是我们进入了旧的C++之类的东西 - 它只是一个不足以成为例外的错误.


Lig*_*ica 5

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

代码是正确的。这正是您应该检查流状态的方式。