我真的无法理解为什么在执行这样的循环时,调试器没有进入 std::cin的实现(cin 是 while 中的那个)。请解释为什么会这样。
int choiceMenu = 0;
std::cin >> choiceMenu;
while (choiceMenu < 1 || choiceMenu > 5 || std::cin.fail()) {
std::cout << "Invalid choice, try again: ";
std::cin >> choiceMenu;
}
读取整数时,如果输入流包含不代表数字的字符序列,或者输入流包含的数字超出目标类型的可表示值范围,则输入流设置内部错误标志
failbit
。任何进一步的输入尝试都将被忽略。此外,如果无法计算数量,因为 不是流中的数字,则不会从输入流中提取无效的字符序列。如果您只是重置错误标志,那么进一步的输入将继续使用不正确的字符序列。
因此,在尝试再次读取数字之前,有必要使用函数重置错误标志
clear()
,并清除输入流中的错误字符。要从无效字符中清除输入流,您可以使用以下函数
ignore()
:它从流中提取字符,直到它完全提取
count
字符,直到它到达文件的末尾,或者直到它到达分隔符delim
(也将被提取)。如果参数count
等于整数类型表示的最大值,则不检查std::streamsize
提取的字符数是否与参数相等。count
或多或少是这样的:
有可能是号码读取成功,但条件满足
choiceMenu < 1 || choiceMenu > 5
。ignore()
理论上,这种情况下的调用不应该产生问题,因为 它只会提取输入流中剩余的换行符。还要记住,像这样的一行
上面的代码被认为是有效的输入。变量
choiceMenu
将被赋值2
,字符序列将在循环后被test
函数读取。ignore()
如果我们使用输入重定向,使输入流从文件中读取数据,并且文件为空,那么上面的输入循环将变成无限的。
我们试图从一个空文件中读取一个数字 - 什么也没发生,设置标志
failbit
和eofbit
.我们清除了错误标志,再次尝试从空文件中读取数字 - 没有发生任何事情。
我们再次清除标志,再次尝试计数,等等。
另外,在读取过程中,可以设置flag
badbit
,表示流的工作中存在一些非常严重的问题。因此,上面的代码可能应该被重写为:
链接到示例。