请考虑以下简单示例
#include
#include
#include
using namespace std;
int main() {
string str = "string";
istringstream is(str);
is >> setw(6) >> str;
return is.eof();
}
乍一看,由于显式宽度由setw操纵器指定,我期望>>运算符在从输入流中成功提取所请求的字符数后完成读取字符串.我没有看到它试图提取第七个字符的任何直接原因,这意味着我不希望流进入eof状态.
当我在MSVC下运行这个例子时,它按照我的预期工作:读取后流保持良好状态.但是,在GCC中,行为是不同的:流最终处于eof状态.
语言标准,它为此版本的>>提供了以下完成条件列表.操作者
n characters are stored;
end-of-file occurs on the input sequence;
isspace(c,is.getloc()) is true for the next available input character c.
鉴于上述情况,我认为>>没有任何理由.运算符在上面的代码中将流驱动到eof状态.
...
__int_type __c = __in.rdbuf()->sgetc();
while (__extracted < __n
&& !_Traits::eq_int_type(__c,__eof)
&& !__ct.is(__ctype_base::space,_Traits::to_char_type(__c)))
{
if (__len == sizeof(__buf) / sizeof(_CharT))
{
__str.append(__buf,sizeof(__buf) / sizeof(_CharT));
__len = 0;
}
__buf[__len++] = _Traits::to_char_type(__c);
++__extracted;
__c = __in.rdbuf()->snextc();
}
__str.append(__buf,__len);
if (_Traits::eq_int_type(__c,__eof))
__err |= __ios_base::eofbit;
__in.width(0);
...
如您所见,在每次成功迭代结束时,它会尝试为下一次迭代准备下一个__c字符,即使下一次迭代可能永远不会发生.在循环之后,它分析该__c字符的最后一个值并相应地设置eofbit.
所以,我的问题是:在上述情况下触发eof流状态,就像GCC那样 – 从标准的角度来看它是合法的吗?我没有在文档中明确指出它. MSVC和GCC的行为是否合规?或者只是其中一个表现正常?