如何解决如果第一次读取失败,则 std::istream::unget() 设置失败和坏位,但如果第二次或进一步读取失败则不会
#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;
}
如果我输入一个或多个数字后跟一个单词(例如 1hola
、1 2 3 quit
),is.unget()
既不会设置失败位也不会设置坏位,并且我获取预期的输出消息(例如 Exiting with an error. User typed: hola
、Exiting correctly
)。
但是如果我只是输入一个单词(例如 hola
或 quit
),is.unget()
会设置失败位和错误位,我无法恢复最后一个输入,得到消息 {{ 1}}。
对于后一种情况,为什么我们不能将从流中读取的任何内容放回其中?
解决方法
您的错误似乎是认为在读取整数和非数字时发现字符被消耗了。不是。只需删除对 std::unget
的调用。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。