【问题标题】:Why does std::ios_base::ignore() set the EOF bit?为什么 std::ios_base::ignore() 设置 EOF 位?
【发布时间】:2017-03-11 12:33:36
【问题描述】:

当我从流中读取所有数据,但不尝试读取超过其末尾的内容时,流的 EOF 未设置。这就是 C++ 流的工作方式,对吧?这就是它起作用的原因:

#include <sstream>
#include <cassert>

char buf[255];

int main()
{
    std::stringstream ss("abcdef");
    ss.read(buf, 6);

    assert(!ss.eof());
    assert(ss.tellg() == 6);
}

但是,如果不是read()ing data I ignore() it,则设置 EOF:

#include <sstream>
#include <cassert>

int main()
{
    std::stringstream ss("abcdef");
    ss.ignore(6);

    assert(!ss.eof());        // <-- FAILS
    assert(ss.tellg() == 6);  // <-- FAILS
}

这是在 GCC 4.8 和 GCC 主干 (Coliru) 上。

它还有一个不幸的副作用是让tellg() 返回-1(因为这就是tellg() 所做的),这对我正在做的事情来说很烦人。

这是标准规定的吗?如果有,是哪一段,为什么?为什么ignore() 会尝试阅读比我告诉它的更多的内容?

我在cppreference's ignore() page 上找不到这种行为的任何原因。我可能可以.seekg(6, std::ios::cur) 代替,对吧?但我还是想知道发生了什么。

【问题讨论】:

  • 哇,这适用于 MSVS。它在 coliru 上的叮当声也失败了。我认为它可能是库而不是编译器本身。
  • 如果您指定除eof 之外的其他delim 会发生什么?
  • @dwcanillas: No change.
  • @LightnessRacesinOrbit 看起来this bug 是同一个问题。

标签: c++ c++11 std iostream


【解决方案1】:

我认为这是一个 libstdc++ 错误(42875h/tNathanOliver)。 [istream.unformatted] 中对ignore() 的要求是:

字符被提取,直到任何 发生以下情况:
— 到目前为止,n != numeric_limits&lt;streamsize&gt;::max() (18.3.2) 和 n 字符已被提取
— 文件结束出现在输入序列上(在这种情况下,函数调用setstate(eofbit), 这可能会抛出 ios_base::failure (27.5.5.4));
traits::eq_int_type(traits::to_int_type(c), delim) 用于下一个可用的输入字符 c(在这种情况下,c 被提取)。
备注:如果traits::eq_int_type(delim, traits::eof()),则不会出现最后一个条件。

所以我们有两个条件(最后一个被忽略)——我们要么读取n 字符,要么在某些时候遇到文件结尾,在这种情况下我们设置eofbit。但是,在这种情况下,我们能够从流中读取 n 字符(实际上您的流中有 6 个字符),因此我们不会在输入序列上命中文件结尾。

在 libc++ 中,eof() 未设置,tellg() 确实返回 6。

【讨论】:

  • 很高兴您同意。 :)
  • 正如报告中指出的那样,要求过于模糊,无法清楚地将其标记为 libstdc++ 中的错误,这似乎更像是标准中的缺陷。可以说,该措辞允许实现首先检查是否命中 EOF,然后仅检查是否已经提取了 n 字符。或者检查n字符是否已经被提取,然后检查是否命中EOF,最后结合两个检查的结果。
  • @hvd:可以说。
  • @hvd 我不知道...肯定违反了这里对操作正常工作方式的期望原则。
  • @Barry 同意。如果它旨在允许 libstdc++ 的实现(这让我感到惊讶),那么我希望标准以明确允许的方式说明要求。
猜你喜欢
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-28
  • 2012-11-19
  • 2014-06-20
  • 1970-01-01
  • 2015-01-15
相关资源
最近更新 更多