【问题标题】:c++ ifstream fail() flag is on but no error shown by strerror()c++ ifstream fail() 标志打开但 strerror() 没有显示错误
【发布时间】:2021-02-26 01:08:18
【问题描述】:

我有如下代码。我觉得文件流没有到达文件末尾,因为ln_cnt的值不等于QGIS中显示的特征计数(即折线特征的数量)。

当 shapefile 很大时会发生这种不等式,因此我无法逐个计算特征,但我已经使用小型 shapefile 进行测试,并且我的代码运行良好。

polyline_class line_1;

int ln_cnt ++; // the counter for counting the lines that's read

ifstream reader("some_polyline.shp", ios::in | ios::binary);

while (!reader.eof()){

    shp_read_pnt(&reader, &line_1);
    ln_cnt ++;

}

cout << ".good() = " << reader.good() << "\n";
cout << ".bad() = " << reader.bad()   << "\n";
cout << ".fail() = " << reader.fail() << "\n";
cout << ".eof() = " << reader.eof()   << "\n";
cerr <<  "Error: " << strerror(errno);
reader.close();

结果是:

.good() = 0
.bad() = 0
.fail() = 1
.eof() = 1
Error: No error

真的有错误吗?

【问题讨论】:

  • 在主题上,很多事情都可能发生在不会设置errno 的流中,因此对strerror 没有影响。在这种情况下,看起来流确实到达了文件的末尾。不是errno 关心的那种事情。这是在讨论 C,但最终结果将是相似的:Does EOF set errno?
  • ln_cnt 甚至没有在您发布的代码中初始化。如果您想要有用的答案,您应该发布一个可重现的示例。
  • int ln_cnt ++; 不是有效的表达式。你需要int ln_cnt = 0;

标签: c++ c++11 c++17


【解决方案1】:

TL;DR“好”不是“坏”的对立面,“好”是“失败”的对立面

iostream 有两个1 持久状态位,用于记录流上先前操作的结果。这两个位都是“粘性的”——它们开始为假,并在某些事情发生时设置为真,然后保持真直到通过调用 clear() 明确清除它们

  • eof:如果由于到达文件末尾而无法读取数据,则设置此设置
  • bad:如果底层设备发生错误则设置

eof() 和 bad() 函数会检查这些位,fail() 会检查这两个位(所以fail() == eof() || bad())。 现在令人困惑的部分 - good() 同时检查了两者,所以好的 IS NOT 与坏的相反。而是good() == !fail()。

差不多就是这样,并解释了您所看到的结果。你读到了文件的结尾,所以设置了 eof 位,但从来没有任何错误,所以 bad 仍然清楚。你有 fail() == eof() || bad() 和 good() == !fail() ,正如人们所期望的那样。


1好吧,从技术上讲,上面的内容是错误的 - 可能存储了更多位(包括好位和失败位),但总体而言行为如上面所解释的那样 - 当设置了 bad 或 eof 位时,将设置失败位,并且只有在其中一个设置时才会设置。当设置失败位时,好位将始终被清除。与上述不一致的唯一方法是用户手动将这些位设置为与clear(some-odd-state) 的某种奇怪组合,但不清楚为什么有人会这样做。 clear() 设置的默认状态(仅)设置了好位。

【讨论】:

    【解决方案2】:

    没有真正安全的方法来判断,因为您显然没有发布所有代码(例如,缺少 shp_read_pnt() 的实现),但无论如何我都会尝试:

    std::ifstream 的读取操作(通常)根本不需要设置errno。或者换句话说:std::ifstream 的读取操作之一失败并且仍然没有设置 errno 可能是完全合法的。

    C++ 流通常使用异常或各种错误位(可以使用fail()、bad() 等查询)来表示出现问题。所以应该使用这些而不是errno。

    【讨论】:

      猜你喜欢
      • 2021-12-08
      • 2014-07-28
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 1970-01-01
      • 2019-05-12
      • 1970-01-01
      相关资源
      最近更新 更多