简体   繁体   English

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

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

Recently I've come across a bug in my software that was caused by a stringstream object that had it's EOF flag set before I expected it. 最近,我遇到了我的软件中的一个错误,该错误是由一个stringstream对象引起的,该对象在我预期之前设置了EOF标志。 Even though I managed to found out what happened, I was not able to find out why this is happening. 即使我设法找出发生了什么,但仍无法找出发生这种情况的原因。 An example: 一个例子:

stringstream test ("a b");
char temp, temp2;

test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;  

When run, this shows: 运行时,显示:

eof: 0

This is the output I would expect. 这是我期望的输出。 (I would expect the stringstream to set the EOF flag to 1 when i attempt to read something again) (当我再次尝试读取内容时,我希望stringstream将EOF标志设置为1)

However, when I make a small change to the above example: 但是,当我对上面的示例进行一些小的更改时:

stringstream test ("4 2");
int temp, temp2;

test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;

the output shows: 输出显示:

eof: 1

Why does the EOF flag get set in this situation, but not in the previous one? 为什么在这种情况下会设置EOF标志,而在前一种情况下却未设置呢?

When you're extracting one character at a time, the stream can't know that the EOF has been reached until you try to extract a character that isn't there. 当你在一个时间提取一个字符,流无法知道EOF已经达到,直到尝试提取一个字符,是不存在。

But when you're extracting formatted data into a type like int , the parser attempts to pull as many characters out of the stream as it can to form the number; 但是,当您将格式化的数据提取为int类的类型时,解析器将尝试从流中拉出尽可能多的字符以形成数字。 the "tries to extract a character that isn't there" part will occur as part of this process (the final "iteration", in fact), so EOF can be set. “尝试提取不存在的字符”部分将作为此过程的一部分(实际上是最终的“迭代”),因此可以设置EOF。

operator>> skips whitespace characters by default, so the first read into a char will read a , the second will skip 默认情况下, operator>>跳过空格字符,因此第一次读入char的字符将读取a ,第二次将跳过 and read b , a third would reach the end of the string and fail, setting the eof flag. 并读取b ,三分之一将到达字符串的末尾并失败,设置eof标志。

In the int case, multiple characters can be read while parsing an int because an int may be represent by multiple digits. int情况下,解析int可以读取多个字符,因为int可能由多个数字表示。 While reading the integer a second read attempt will be made after reading the 2 . 在读取整数时,将在读取2之后进行第二次读取尝试。 This will set the eof flag for the stream although the read of the int will succeed. 尽管将成功读取int这将为流设置eof标志。

This is why you should check !fail() and not good() to see if a read operation succeeded and why the conversion of a stream to bool (or void* in C++03) also uses !fail() . 这就是为什么您应该检查!fail()而不是good()来查看读取操作是否成功的原因,以及为什么将流转换为bool (在C ++ 03中为void* )也使用!fail()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM