【问题标题】:unexpected behavior when read a character from istringstream从 istringstream 读取字符时出现意外行为
【发布时间】:2014-12-19 18:20:47
【问题描述】:

我对流行为有疑问,请参阅以下示例。我期待的是 ss_char 和 ss_int 将是 eof 状态,但只有 ss_int 将是 eof 状态。

我的问题是,为什么不是 ss_char eof 状态? 不能用 operator>>,只用 istringstream::get() 函数,那为什么读取值成功呢?

输出:
字符值:a
整数值:42

ss_char eof: false // 为什么是假的?
ss_int eof: 真

对不起,我的英语很差。我正在努力提高我的英语水平。

#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;
}

【问题讨论】:

  • 区别在于ss_char只需要提取单个字符,而ss_int会继续扫描直到找到空格或文件结尾。

标签: c++


【解决方案1】:

CppReference 说:“这个函数只报告最近 I/O 操作设置的流状态,它不检查关联的数据源。例如,如果最近的 I/O 是 get(),返回文件的最后一个字节,eof() 返回 false。下一个 get() 读取任何内容失败并设置 eofbit。只有这样 eof() 返回 true。"

当读取操作试图读取超出文件末尾时,oefbit 将变为真,但当它完全读取到文件末尾而不尝试更进一步时则不会。当你读取char时,它知道它应该读取一个字节,所以这个读取操作是可以的,读取位置提前1个字节,到最后,但是假设流仍然没有注意到它确实是最后,如果您尝试阅读其他内容,它会。当你读取一个整数时,它会尝试读取超过 42,因为整数的长度不清楚,它可能是 42901,所以它必须读取直到它看到一个空格,和行尾,或者最终如果没有其他可读取的文件/流。

运算符>>的结果是流本身。当它被转换为 void*(或 bool,取决于 c++11 或以前的版本)时,它作为 !fail() 工作,因此它会告诉您读取或写入操作是否正常,无论它是否到达文件末尾(如果现在已经结束,则下一次读取操作将失败)。

【讨论】:

    【解决方案2】:

    EOF 条件实际上不会发生,直到您尝试读取 流的末尾。

    char 的情况下,您只能读取一个字符,唯一可用的字符。你不要试图读到结尾,因为没有必要。

    另一方面,提取int 会尝试使用尽可能多的数字。它读取 4 和 2,然后尝试再次读取以查看是否还有其他数字要消耗,在这种情况下,它确实尝试读取末尾。它注意到输入已经结束,因此完成了 42 的转换。

    【讨论】:

      【解决方案3】:

      提取字符时,它会一次提取一个字符,并在连续调用时跳过空格。

      在提取 int 时,解析器会尝试提取尽可能多的字符来形成数字。这会导致整数提取在您的测试用例中达到 eof。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-01-02
        • 2017-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-16
        • 1970-01-01
        • 2016-01-23
        相关资源
        最近更新 更多