繁体   English   中英

为什么从流中提取字符串会设置eof位?

[英]Why does string extraction from a stream set the eof bit?

假设我们有一个简单的流:

hello

请注意,没有多余的\\n在最后像有经常是一个文本文件。 现在,以下简单代码显示在提取单个std::string后,在流上设置了eof位。

int main(int argc, const char* argv[])
{
  std::stringstream ss("hello");
  std::string result;
  ss >> result;
  std::cout << ss.eof() << std::endl; // Outputs 1
  return 0;
}

但是,我不明白为什么会根据标准发生这种情况(我正在阅读C ++ 11 - ISO / IEC 14882:2011(E) )。 operator>>(basic_stream<...>&, basic_string<...>&)被定义为行为类似于格式化的输入函数 这意味着它构造了一个sentry对象,它继续吃掉空白字符。 在这个例子中,没有,所以sentry结构完成没有问题。 当转换为boolsentry对象给出true ,因此提取器继续继续实际提取字符串。

然后将提取定义为:

提取并附加字符,直到出现以下任何一种情况:

  • 存储n字符;
  • 文件结束发生在输入序列上;
  • 对于下一个可用的输入字符c isspace(c,is.getloc())为true。

在提取最后一个字符(如果有)之后,调用is.width(0)并销毁sentry对象k。 如果函数没有提取任何字符,则调用is.setstate(ios::failbit) ,这可能会抛出ios_base::failure (27.5.5.4)。

这里没有任何东西实际上导致eof位被设置。 是的,如果提取到达文件结尾,则提取停止,但它不会设置该位。 事实上,只有当我们做另一个ss >> result;才应该设置eofss >> result; ,因为当sentry试图吞噬空白时,会发生以下情况:

如果is.rdbuf()->sbumpc()is.rdbuf()->sgetc()返回traits::eof() ,则函数调用setstate(failbit | eofbit)

但是,这肯定没有发生,因为没有设置failbit

eof位被设置的结果是,当读取文件时,邪恶习惯while (!stream.eof())不起作用的唯一原因是因为最后的额外\\n不是因为eof位不是还没设定。 当提取在文件末尾停止时,我的编译器很乐意设置eof位。

这应该发生吗? 或者标准是否意味着应该发生setstate(eofbit)


为方便起见,标准的相关部分是:

  • 21.4.8.9插入器和提取器[string.io]
  • 27.7.2.2格式化输入函数[istream.formatted]
  • 27.7.2.1.3 class basic_istream::sentry [istream :: sentry]

std::stringstream是一个basic_istreamstd::stringoperator>>从中提取“字符”(如你basic_istream )。

27.7.2.1类模板basic_istream

2如果rdbuf() - > sbumpc()或rdbuf() - > sgetc()返回traits :: eof(),则输入函数除非另有明确说明,否则完成其操作并执行setstate(eofbit),在返回之前抛出ios_- base :: failure(27.5.5.4)。

此外,“提取”意味着调用这两个函数。

3两组成员函数签名共享公共属性:格式化的输入函数(或提取器)和未格式化的输入函数。 两组输入函数都被描述为通过调用rdbuf() - > sbumpc()或rdbuf() - > sgetc()来获取(或提取)输入字符。 他们可能会使用istream的其他公共成员。

所以必须设置eof。

直观地说,设置EOF位是因为在读取操作期间提取字符串时,流确实命中了文件的末尾。 具体来说,它连续从输入流中读取字符,因为它在遇到空白字符之前到达流的末尾而停止。 因此,流设置EOF位以标记到达流的末尾。 请注意,这是一样的报告失效-在操作成功完成-但EOF位点是不报告故障。 这是为了标记遇到流的末尾。

我没有特定的规范来支持这一点,但是当我有机会的时候我会尝试寻找一个。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM