1

我想写一个围绕fstream类的包装器。正如我所看到的,检查流是否正常工作的最常见方法是查看good()函数的结果。但是,我听说这主要是历史函数,使用它并不是很安全(更正确地说,可能有一些情况 stream 不能正常工作但函数返回true。所以我想分享经验并从其他人那里知道检查fstream错误的最正确方法是什么。

如果有可能检查不同类型的错误,例如文件是否不存在,只能打开以供阅读等,那就太好了。还必须将此类程序保留为跨平台(但是,主要目标是Linux)。

提前致谢!

4

3 回答 3

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 等的读/写操作期间,这个问题的第一个答案看起来很有见地。

于 2013-07-05T14:52:27.680 回答
1

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

于 2013-07-05T14:32:01.403 回答
0

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

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

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

C++ 流还重载运算符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;
  }
于 2020-02-26T11:41:13.630 回答