当我从流中读取所有数据,但没有尝试读取超过其末尾的数据时,流的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的ignore()
页面上找不到这种行为的任何原因。我可能可以改为.seekg(6, std::ios::cur)
,对吧?但我还是想知道发生了什么。
我认为这是一个libstdc++错误(42875,h/t NathanOliver(。[isream.unformated]中对ignore()
的要求为:
字符被提取,直到发生以下情况之一:
--到目前为止,已经提取了n != numeric_limits<streamsize>::max()
(18.3.2(和n
字符
--文件结尾出现在输入序列上(在这种情况下,函数调用CCD_,可能抛出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。