示例:
int i=0;
do {
cin >> i;
if(!isdigit(i)) cout << "Error. Must be an integer\n\n";
}
while(cin.fail());
如果用户输入了字符而不是整数,程序会因某种原因而中断并进入某个无限循环。为什么是这样?有没有办法防止它发生? isdigit()函数似乎不适用于int
个变量,只适用于char
个变量。
答案 0 :(得分:3)
您似乎对输入的工作原理感到困惑。当你写
std::cin >> i;
和i
是int
,输入流将提取文本
一个整数值:它将跳过空格,然后提取
一个可能的符号,然后是一个或多个数字。然后它会转换
将此文本转换为int
,并将其存储在请求的位置。如果它
没有找到相应格式的文本,它会设置一个
错误状态(failbit
),在您清除之前将保持设置状态
它。它将不修改i
;你必须经常检查
在使用变量输入之前输入已成功。
isdigit
具有未定义的行为,除非
传递的整数在[0,UCHAR_MAX]
范围内。 (注意
那个范围。这意味着您不能简单地将其传递给char
。)
目前尚不清楚你在这里要做什么。如果只是
输入int
:
int i;
while ( !(std::cin >> i) ) {
std::cout << "Error: integer wanted" << std::endl;
std::cin.clear(); // Clear error...
std::cin.ignore( INT_MAX, '\n' ); // And ignore characters which caused it
// (up until next '\n')
}
如果你想要一个数字:
int i = std::cin.get();
while ( i != EOF && !isdigit( i ) ) {
std::cout << "Error, single digit wanted" << std::endl;
i = std::cin.get();
}
char ch = i; // NOW (and only now) can you convert into int.
std::cin.get()
会返回int
,以便处理
带值EOF
。 int
保证在范围内
[0...UCHAR_MAX]
,或EOF
,因此您可以直接传递它
到isdigit
。只有在你完成这些测试后才应该
将其转换为char
(因为数字是一个字符)。
答案 1 :(得分:2)
您始终需要在>> 之后检查输入是否成功,例如
if (std::cin >> i) {
// process input
}
如果输入失败,则设置std::ios_failbit
。设置此标志时,流将不接受任何输入并转换为false
。要清除错误标记,请使用
std::cin.clear();
清除错误标志不会删除有问题的字符。你需要摆脱它们,例如,使用
std:: ignore();
答案 2 :(得分:0)
上面的代码肯定不会创建无限循环。但是循环通常发生在预期数字并且给出非数字时,因此缓冲区中的字符将保留在那里并且流处于错误状态。这将在流被适当清除之前发生,以便stdio可以根据格式规范继续读取。当然循环必须在我们的程序中完成,因为stdio不是自己循环。
要清除输入和输入内容,您可以使用:
std::cin.clear();
std::cin.ignore();