为什么字符串提取从设置EOF比特流?(Why does string extraction from

2019-07-18 22:50发布

比方说,我们有一个包含一个简单的流:

hello

请注意,没有多余的\n在最后像有经常是一个文本文件。 现在,下面简单的代码表明eof位提取单后的数据流来设置std::string

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建设没有问题完成。 当转换为bool时, sentry对象给出了true ,所以提取继续获得与该字符串的实际提取。

提取被定义为:

字符被提取和所附直到任何下列情况发生:

  • n字符被存储;
  • 档案结尾发生在输入序列;
  • isspace(c,is.getloc())是用于下一个可用的输入字符c真。

的最后一个字符(如果有的话)被提取后,is.width(0)被称为和岗哨对象k被破坏。 如果函数提取没有字符,它调用is.setstate(ios::failbit)这可能会引发ios_base::failure (27.5.5.4)。

这里没有什么实际导致eof位进行设置。 是的,如果它击中结束的文件,但它不设置比特提取停止。 事实上, eof位才应该设置,如果我们做另外一个ss >> result; ,因为当sentry企图吞噬的空白,将发生以下情况:

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

但是,这绝对不是因为尚未发生failbit未设置。

的的后果eof被设置位是唯一的原因恶成语while (!stream.eof())当读取文件是因为额外的不起作用\n在最后并没有因为eof位ISN “T尚未设定。 我的编译器愉快地设置eof位时提取停止在文件的结尾。

所以这应该是这样吗? 或者没有标准的意思是说, setstate(eofbit)应该发生?


为了更方便,标准的相关章节是:

  • 21.4.8.9插入器和提取器[string.io]
  • 27.7.2.2格式化输入功能[istream.formatted]
  • 27.7.2.1.3类basic_istream::sentry [istream的::岗哨]

Answer 1:

std::stringstreambasic_istreamoperator>>std::string从中“提取物”的字符(如你发现了)。

27.7.2.1类模板basic_istream

2如果rdbuf() - > sbumpc()或rdbuf() - > sgetc()返回性状:: EOF(),则输入功能,除非明确地指出,否则,完成它的操作并执行setstate这(eofbit),其可以返回前扔ios_-基地::失败(27.5.5.4)。

此外,“提取”是指调用这两个函数。

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

所以EOF必须设置。



Answer 2:

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

我没有规范的特定部分来支持这一行动,但我会尽量找一个,当我得到机会。



文章来源: Why does string extraction from a stream set the eof bit?