C++ 为什么IOStream和#x27;提取到'char'与'int'时的EOF标志行为?

C++ 为什么IOStream和#x27;提取到'char'与'int'时的EOF标志行为?,c++,iostream,eof,C++,Iostream,Eof,最近,我在我的软件中遇到了一个bug,它是由一个stringstream对象引起的,它的EOF标志设置在我预期的时间之前。尽管我设法找出了发生的事情,但我还是无法找出为什么会发生这种情况。例如: stringstream test ("a b"); char temp, temp2; test >> temp >> temp2; cout << "eof: " << test.eof() << endl; 这是我所期望的结果。(

最近,我在我的软件中遇到了一个bug,它是由一个stringstream对象引起的,它的EOF标志设置在我预期的时间之前。尽管我设法找出了发生的事情,但我还是无法找出为什么会发生这种情况。例如:

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

test >> temp >> temp2;
cout << "eof: " << test.eof() << endl;  
这是我所期望的结果。(当我再次尝试读取某些内容时,我希望stringstream将EOF标志设置为1)

但是,当我对上述示例进行一个小更改时:

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

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

为什么在这种情况下设置EOF标志,而在前一种情况下不设置

当您一次提取一个字符时,流无法知道是否已达到EOF,除非您尝试提取一个不存在的字符


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

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


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

操作符>
默认情况下跳过空白字符,因此读取到字符中的第一个字符将读取
a
,第二个将跳过
并读取
b
,第三个将到达字符串末尾并失败,设置eof标志

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


这就是为什么您应该选中
!fail()
和not
good()
查看读取操作是否成功,以及将流转换为
bool
(或C++03中的
void*
)的原因也使用
!fail()

操作符>
默认情况下跳过空白字符,因此第一个读取到字符中的字符将读取
a
,第二个将跳过
并读取
b
,第三个将到达字符串末尾并失败,设置eof标志

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


这就是为什么您应该选中
!fail()
和not
good()
查看读取操作是否成功,以及将流转换为
bool
(或C++03中的
void*
)的原因也使用
!fail()

我不希望stringstream在再次读取后在初始示例中设置EOF。我希望在第四次读取尝试时看到它。现在决定将其标记为“bug”还为时过早;这只是你身上的一只虫子!它也不特定于
stringstream
s。我不希望stringstream在再次读取后在初始示例中设置EOF。我希望在第四次读取尝试时看到它。现在决定将其标记为“bug”还为时过早;这只是你身上的一只虫子!它也不是特定于
stringstream
s的!eof(eof)
基本上不应该单独检查,这是一个很好的观点。非常感谢Charles,你的解释非常清楚。这确实也发生在阅读字符串,这是有道理的,因为你的文章。我也不清楚什么时候检查位,但是好的检查所有,而“流本身”(一元!我想)只检查坏的/失败的。对于bug标签,我感到抱歉,我更倾向于“程序中的bug”,而不是语言/编译器中的大bug!哦,你说得对。“我不确定我是否会想到这点。”@TomalakGeret'kal:是的
eof()
good()
bad()
fail()
中最难看的一个!eof(eof)
基本上不应该单独检查,这是一个很好的观点。非常感谢Charles,你的解释非常清楚。这确实也发生在阅读字符串,这是有道理的,因为你的文章。我也不清楚什么时候检查位,但是好的检查所有,而“流本身”(一元!我想)只检查坏的/失败的。对于bug标签,我感到抱歉,我更倾向于“程序中的bug”,而不是语言/编译器中的大bug!哦,你说得对。“我不确定我是否会想到这点。”@TomalakGeret'kal:是的
eof()
good()
bad()
fail()
中最难看的。
stringstream test ("4 2");
int temp, temp2;

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