std::istream::unget() 如果第一次读取失败则设置失败和坏位,但如果第二次或进一步读取失败则不设置

std::istream::unget() setting fail and bad bits if first read failed but not if second or further reads failed

我有以下代码:

#include <algorithm>
#include <ios>
#include <iostream>
#include <string>
#include <vector>

std::vector<int> read_ints(std::istream& is)
{
    std::vector<int> res;

    std::cout << "Please input a list of integers ('quit' to finish):" << std::endl;
    for (int i; is >> i; )
    {
        res.push_back(i);
    }
    if (is.eof())  // fine: end of file
    {
        std::cout << "EOF reached" << std::endl;
        return res;
    }
    std::cout << (is.bad() ? "1) BAD\n" : "");
    std::cout << (is.fail() ? "1) FAIL\n" : "");
    if (is.fail())  // we failed to read an int: was it the 'quit' string?
    {
        is.clear();  // reset the state to good
        std::cout << (is.bad() ? "2) BAD\n" : "");
        std::cout << (is.fail() ? "2) FAIL\n" : "");
        is.unget();  // put the non-digit back into the stream
        std::cout << (is.bad() ? "3) BAD\n" : "");
        std::cout << (is.fail() ? "3) FAIL\n" : "");
        std::string s;
        if (is >> s && s == "quit")
        {
            std::cout << "Exiting correctly" << std::endl;
            return res;
        }
        std::cout << "Exiting with an error. User typed: " << s << std::endl;
        is.setstate(std::ios_base::failbit);  // add fail() to stream's state
    }
    return res;
}

int main()
{
    // Read ints
    auto v = read_ints(std::cin);
    bool first = true;
    std::for_each(v.begin(), v.end(),
        [&first](int n) { std::cout << (first ? "" : " ") << n; first = false; });
    std::cout << std::endl;
}

如果我输入一个或多个数字后跟一个单词(例如1hola1 2 3 quit),is.unget()既不会设置失败位也不会设置错误位,我得到了预期的输出消息(例如 Exiting with an error. User typed: holaExiting correctly)。

但是如果我只输入一个词(例如holaquit),is.unget()设置失败位和错误位,我无法恢复最后的输入,得到消息Exiting with an error. User typed:.

对于后一种情况,为什么我们不能将从流中读取的任何内容放回流中?

https://godbolt.org/z/dMoodE

你的错误似乎是认为当读取一个整数和一个非数字时发现字符被消耗了。它不是。只需删除对 std::unget.

的调用