为什么std::ios_base::ignore()设置EOF位



当我从流中读取所有数据,但没有尝试读取超过其末尾的数据时,流的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。

最新更新