为什么当我提取到"char"和"int"时,IOStream的EOF标志行为会有所不同?

Why the difference in IOStream's EOF flag behaviour when I extract to `char` vs to `int`?

本文关键字:标志 EOF 有所不同 IOStream 提取 char 为什么 int      更新时间:2023-10-16

最近我在我的软件中遇到了一个错误,这是由一个stringstream对象在我预期之前设置了EOF标志引起的。尽管我设法弄清楚发生了什么,但我无法找出发生这种情况的原因。一个例子:

stringstream test ("a b");
char temp, temp2;
test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;  

运行时显示:

eof: 0

这是我所期望的输出。(当我试图再次读取某些内容时,我希望stringstream将EOF标志设置为1)

然而,当我对上面的例子做一个小的改变时:

stringstream test ("4 2");
int temp, temp2;
test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;

输出显示:

eof: 1

为什么在这种情况下设置了EOF标志,而在前一种情况下没有设置?

当您每次提取一个字符时,流无法知道EOF已经到达,直到尝试提取不存在的字符。

但是,当您将格式化的数据提取到像int这样的类型时,解析器会尝试从流中提取尽可能多的字符以形成数字;"尝试提取不存在的字符"部分将作为此过程的一部分(实际上是最后的"迭代")发生,因此可以设置EOF。

operator>>默认跳过空白字符,因此第一次读入字符将读取a,第二次将跳过并读取int,第三次将到达字符串的末尾并失败,设置eof标志。

int的情况下,解析int时可以读取多个字符,因为2可以由多个数字表示。当读取整数时,在读取int之后将进行第二次读取尝试。这将为流设置eof标志,尽管读取!fail()将成功。

这就是为什么你应该检查good()而不是bool来查看读操作是否成功,以及为什么将流转换为void*(或c++ 03中的!fail())也使用CC_15。