C++ 而带有try-catch的循环在输入错误时失败
我似乎不明白为什么在得到非int输入后会陷入循环。我试过cin.flush(),它似乎不存在,cin.clear(),它似乎应该可以工作,甚至在阅读了其他人关于它工作的帖子后,我试过了cin.sync(),但似乎没有多大意义。还尝试了cin.bad() 非常感谢你的帮助 请输入第一个数字:f 对不起,我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字?对不起, 你不会再有机会了。按 任何继续的钥匙C++ 而带有try-catch的循环在输入错误时失败,c++,try-catch,iostream,while-loop,C++,Try Catch,Iostream,While Loop,我似乎不明白为什么在得到非int输入后会陷入循环。我试过cin.flush(),它似乎不存在,cin.clear(),它似乎应该可以工作,甚至在阅读了其他人关于它工作的帖子后,我试过了cin.sync(),但似乎没有多大意义。还尝试了cin.bad() 非常感谢你的帮助 请输入第一个数字:f 对不起,我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起, 我不认为这是一个数字 请输入第一个号码:对不起,
#包括
使用名称空间std;
int main(){
整数输入;
int=1;
int结果;
同时(试图进入;
if(cin.fail())
抛出“对不起,我不认为这是一个数字?”;
如果(条目<0)
抛出“对不起,没有负数。试试别的?”;
不能进入;
cin.clear();
cin.get();
}
捕获(字符*错误){
法庭(5)
cout为什么要对异常执行此操作?您不会在输入时终止程序,因此不应该抛出异常
只需打印出您的错误消息并尝试再次读取。看起来您最好使用iostream
的本机异常。使用
cin.exceptions( ios::failbit );
try {
…
} catch( ios_base::failure & ) {
cin.clear();
…
}
永远不要抛出非源于std::exception
的对象,尤其是像char*
这样的本机类型。在这种情况下,如果用户给出无效输入,您应该仔细考虑该怎么办。通常在这种情况下,最好的解决方案是从输入中读取一行并将其丢弃
尝试将cin.clear()
和std::cin.ignore(std::numeric\u limits::max(),'\n');
放在catch子句中。cin.clear()
清除cin.ignore()中的故障状态,而cin.ignore()
丢弃输入缓冲区中等待的其余行
(是的,您可能应该重新考虑异常的使用)。异常应该用于处理异常、意外的情况。来自用户的错误输入既不是意外的,也不是例外的——这或多或少是正常现象。就我个人而言,我倾向于完全忽略最糟糕的输入(当无法阻止时)。当(而且只有当)他们反复输入一些不可用的东西时,才值得向他们指出。因此,我倾向于编写如下代码:
char ch;
int attempts = 0;
std::cout << "Please enter the first number: ";
do {
cin >> ch;
attempts++;
if (attempts > 5)
std::cerr << "The only allowable inputs are '0' through '9'\n";
} while (cin.good() && !isdigit(ch));
int first_number = ch - '0';
charch;
int=0;
std::cout>ch;
尝试++;
如果(尝试次数>5次)
std::cerr处理基于行的输入验证的最直接(但通常不是最简单也不是最快)的方法是始终一行一行地读取它。这种方法在任何情况下都不会在缓冲区中留下额外的空白(如换行符),并且丢弃错误的输入也是相当自动的
// Infinite loop for retrying until successful
while (true) {
// Ask the user something
std::cout << prompt;
// Read the answer (one full line)
std::string line;
if (!std::getline(std::cin, line))
throw std::runtime_error("End of input while expecting a value");
// Put the line read into iss for further parsing
std::istringstream iss(line);
int val;
// Read val from iss and verify that reading was successful and
// that all input was consumed
if (iss >> val && iss.get() == EOF) return val;
std::cout << "Invalid input, try again!\n";
}
//无限循环,用于重试直至成功
while(true){
//询问用户一些问题
std::cout>val&&iss.get()==EOF)返回val;
std::cout我的问题是阻止对cin>>号的字符输入
此错误导致出现“无限”循环,显示我的提示cout fi_game_sec;cin.clear();}//(2)
catch(…)//超出范围)
{
fi_game_sec=-1;
除非您特别想发出信号,以免它在错误处理中被捕获(C++0x建议的线程API的中断支持使用此技巧中断线程)-1.进行建议的更改不会解决当前的问题,这与引发的异常类型无关,也与异常是由流手动还是自动引发无关。@Rob:但我在示例代码中解决了当前的问题……不,您没有。调用clear
重置错误状态,但缓冲区中仍存在错误输入。读取字符是读取数字(可能不止一个数字)的一种非常糟糕的方式。@Tronic:当然,这就是为什么我说您可能要读取整行并尝试转换。然而,这样做的原因是(至少在正常情况下)用户可以输入的任何内容都将被成功读入字符,因此它们不会停留在输入缓冲区中,从而导致OP询问的问题。-1.忽略手头的问题,这就是代码“在获得非int输入后陷入循环”的原因立即打印错误并使用continue
将产生相同的结果。正如其他人所说,您的异常使用是不合适的。将throw
替换为“std::cerr可能与我的一个类中的问题的解决方案重复。谢谢!:)(是的,我在源代码中添加了指向您的评论的链接)
// Infinite loop for retrying until successful
while (true) {
// Ask the user something
std::cout << prompt;
// Read the answer (one full line)
std::string line;
if (!std::getline(std::cin, line))
throw std::runtime_error("End of input while expecting a value");
// Put the line read into iss for further parsing
std::istringstream iss(line);
int val;
// Read val from iss and verify that reading was successful and
// that all input was consumed
if (iss >> val && iss.get() == EOF) return val;
std::cout << "Invalid input, try again!\n";
}
template <typename Val> void input(std::string const& prompt, Val& val) {
// (the above code goes here, slightly adjusted)
}
int main() {
int w;
double l;
input("Enter weight in kg: ", w);
input("Enter length in m: ", l);
std::cout << "BMI: " << w / (l * l) << std::endl;
}
double fi_trap_d() // function to return a valid range double catching errors
{
double fi_game_sec;
//-------------------------------------------
do
{
fi_game_sec = -1;
cout << fi_game_sec_c;
//------------------------------
cin.ignore(); // (1)
//------------------------------
try
{ cin >> fi_game_sec; cin.clear(); } // (2)
catch (...) //out_of_range)
{
fi_game_sec = -1;
cout << " Dis am an error!\n";
// just loop back as we asked for a number
}
} while (fi_game_sec < 1);
//-------------------------------------------
return fi_game_sec;
}