fstream:检查错误的最正确方法

时间:2013-07-05 14:26:07

标签: c++ exception error-handling io fstream

我想在fstream类附近编写一个包装器。我可以看到检查流是否运行良好的最常用方法是查看good()函数的结果。但是,我听说这主要是历史功能,使用它并不是很安全(更正确的是,在某些情况下,当流不能正常工作但函数返回true时。所以我我想分享经验并向他人了解检查fstream错误的最正确方法。

如果有可能检查不同类型的错误,如果文件不存在,只能打开读取等,那将是很好的。还有必要让这些程序成为跨平台(但是,主要目标是Linux)。

提前致谢!

3 个答案:

答案 0 :(得分:1)

如果文件操作失败,并且eof()返回false,那么您可以检查errnoGetLastError(取决于平台)以找出错误。

答案 1 :(得分:1)

我只有2条建议,它们都依赖于使用重载!运算符的返回值检查打开的流。 使用仅输入模式,只需检查文件是否存在:

char name[] = "C:\\some_folder\\some file.txt";
std::ifstream f;
f.open(name, std::ios::in);
if (!f)
    printf("File does not exist, or inadequate permissions");
f.close();

以进/出模式打开以防止在您计划执行写入操作时将其截断:

std::fstream f;
f.open(name, std::ios::in | std::ios::out);
if (!f)
    printf("Could not open file");
f.close();

默认情况下,这些是各个流的输入参数,但我已明确显示它们以便澄清。

在检查eof等的读/写操作期间,this question的第一个答案看起来很有见地。

答案 2 :(得分:0)

good() / bad()仅测试badbit,后者仅覆盖 some ,并且大部分是不可恢复的错误。要检查错误,您需要同时检查failbitbadbit。有关何时设置这些位的更多详细信息,请参见iosstate

要检查错误,请使用fail(),它同时检查failbitbadbit

  if (stream.fail()) { /* handle error ... */ }

C ++流还会使operator bool重载以返回!fail(),因此您可以轻松做到

  if (!stream) { /* handle error ... */ }

然后,您可以从errno获取最后一个错误,并使用strerror()将其转换为文本:

  std::ifstream f("my_file");
  if (!f) {
      std::cerr << std::strerror(errno) << std::endl;
      return 1;
  }

请注意,failbit包括eofbit(在EOF尝试读取将同时设置两个位),因此,要检查读取错误,您需要排除eofbit

  std::string line;
  while (std::getline(f, line)) {
      // process line
  }
  if (!f && !f.eof()) {
      std::cerr << std::strerror(errno) << std::endl;
  }