使用cin.fail()时存在Ininite循环
Inifinite loop when using cin.fail()
每当我输入无法转换为整数的内容时,我都会得到一个无限循环。有什么建议吗?
cout << "Selection: ";
cin >> choice;
while((choice < 0)||(choice > 6)||(cin.fail())) {
cout << "That isn't a number." << endl;
cin.clear();
cout << "Selection: ";
cin >> choice;
}
仅仅读取clear
是不够的:cin
将一次又一次地读取该字符。你需要ignore
它。
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n')
是实现这一点的常用方法。
另一种方法是将整行读取为字符串,然后对其进行解析(如C#/Java ecc.)
string s;
getline(cin, s);
int n = std::stoi(s);
请注意,std::stoi
可以抛出std::invalid_argument
或std::out_of_range
。使用此方法,您不必忽略任何内容(因此更容易处理/学习),尽管您可能需要捕捉可能的异常。
请注意,即使被其他语言使用,这种方法在逻辑上也是不正确的:只有在异常情况下(例如内部I/O故障),才应抛出异常。相反,错误的用户输入是您所期望的。
这在isocpp.org常见问题中有介绍。它建议使用while (std::cin >> i)
形式的循环,以便在提取失败时终止循环。提取将继续失败,因为std::cin
不会从输入流中提取无效字符。要放弃这些,您需要使用std::cin.ignore
。通常,您可以将任意大的数字作为第一个参数,但习惯使用std::numeric_limits<std::streamsize>::max()
(#include <limits>
)。
循环可以简洁地写为:
while(!(std::cin >> choice) || (choice < 0) || (choice > 6)) {
cout << "Invalid choice." << endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
或者,您可以将提示置于循环条件中:
while((std::cout << "Selection: ")
&& (!(std::cin >> choice) || (choice < 0) || (choice > 6))) {
cout << "Invalid choice." << endl;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
}
不需要"无效字符"诊断,因为它包含在!(std::cin >> choice)
中。示例运行:
Selection: a
Invalid choice.
Selection: b
Invalid choice.
Selection: c
Invalid choice.
Selection: d
Invalid choice.
Selection: 15
Invalid choice.
Selection: 10
Invalid choice.
Selection: 5
相关文章:
- C++模板来检查友元函数的存在
- 既然存在危险,为什么项目要使用-I include开关
- 我们可以访问一个不存在的联盟的成员吗
- C++:对不存在的命名空间使用命名空间指令
- C++quit()函数中可能存在作用域问题
- C++擦除(如果存在)
- g++ 说函数不存在,即使包含正确的标头
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 有了gcc,是否可以链接库,但前提是它存在
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- gcc和clang在表达式是否为常量求值的问题上存在分歧
- C++Builder中的OnClick事件签名存在问题
- 如何正确地将分支添加到已存在的树中
- 我知道函数调用中存在歧义.有没有办法调用foo()函数
- 如何检查QList中是否存在值
- 根据某个函数是否存在启用模板
- 如何将分支添加到已存在的TTree:ROOT
- 地图计数确实很重要,或者只是检查是否存在
- 通用C++/Python 多语言的存在
- 使用cin.fail()时存在Ininite循环