当我从流中读取所有数据但未尝试读取其结束时,未设置流的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()
数据我ignore()
,则设置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)
而不是,对吧?但我仍然想知道发生了什么。
答案 0 :(得分:5)
我认为这是一个libstdc ++ bug(42875,h/t NathanOliver)。 [istream.unformatted]中对ignore()
的要求是:
提取字符直到任何字符 发生以下情况:
- 目前已提取n != numeric_limits<streamsize>::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.