我对流行为有疑问,请参阅以下示例。我期待的是ss_char和ss_int将是eof状态,但只是ss_int将是eof状态。
我的问题是,为什么不是ss_char eof状态? 我不能使用运算符>>,只能使用istringstream :: get()函数,但为什么要成功读取该值?
输出:
char值:a
int值:42
ss_char eof:false //为什么不对?
ss_int eof:true
抱歉我的英语不好。我正努力提高英语水平。
#include <iostream>
#include <sstream>
int main(int /*argc*/, char const * /*argv*/[])
{
char c;
int num;
std::istringstream ss_int("42");
std::istringstream ss_char("a");
if (ss_char >> c)
{
std::cout << "char value: " << c << std::endl;
}
else
{
std::cout << "cannot read char" << std::endl;
}
if (ss_int >> num)
{
std::cout << "int value: " << num << std::endl;
}
else
{
std::cout << "cannot read int" << std::endl;
}
std::cout << std::endl;
std::cout << "ss_char eof: " << std::boolalpha << ss_char.eof() << std::endl; // why false
std::cout << "ss_int eof: " << std::boolalpha << ss_int.eof() << std::endl;
return 0;
}
答案 0 :(得分:0)
CppReference说:“此函数仅报告由最近的I / O操作设置的流状态,它不检查关联的数据源。例如,如果最近的I / O是get(),返回文件的最后一个字节,eof()返回false。下一个get()无法读取任何内容并设置eofbit。只有那时eof()才返回true。“
当读取操作尝试读取超出文件末尾时,oefbit将变为true,但是当它完全读取到文件末尾而不尝试进一步时,它将变为true。当你读取char时,它知道它应该读取一个字节,所以这个读取操作没问题,读取位置前进1个字节,结束,但是说流仍然没有注意到它确实是如果你试着读别的东西,它会结束。当你读取一个整数时,它试图读取超过42,因为整数的长度不清楚,它可能是42901,所以它必须读取,直到它看到一个空格,行尾,或最终结束文件/流,如果没有别的东西可读。
运营商的结果&gt;&gt;是流本身。当它转换为void *(或bool,取决于c ++ 11或之前的版本)时,它的工作原理为!fail(),因此它会告诉您读取或写入操作是否正常,无论它是否到达文件末尾(如果现在结束,则下一次读取操作将失败。)
答案 1 :(得分:0)
在您尝试阅读过去流的结尾之前,EOF条件实际上并未发生。
在char
案例中,您只读了一个字符,唯一可用的字符。你没有尝试阅读结束,因为没有必要。
另一方面,提取int
会尝试消耗尽可能多的数字。它读取4和2,然后它再次尝试读取是否有另一个要消耗的数字, 尝试在这种情况下读取结束。它注意到输入已经结束,因此完成了42的转换。
答案 2 :(得分:0)
提取字符时,它会一次拉出一个字符,并在连续调用时跳过空格。
提取int时,解析器会尝试拉出尽可能多的字符以形成数字。这会导致整数提取在测试用例中达到eof。