当提示输入整数值时输入字符时,为什么程序会中断

Why does a program become broken when a character is input when prompted to input an integer value?

本文关键字:输入 为什么 程序 中断 字符 整数 提示      更新时间:2023-10-16

示例:

int i=0;
do {
cin >> i;
if(!isdigit(i)) cout << "Error. Must be an integernn";
}
while(cin.fail());

如果用户输入的是字符而不是整数,那么由于某种原因,程序会中断并进入某种无限循环。为什么会这样?难道没有办法阻止它发生吗?isdigit()函数似乎不能很好地处理int变量,只能处理char变量。

您似乎对输入的工作方式感到困惑。当你写

std::cin >> i;

并且iint,则输入流将提取一个整数值:它将跳过空白,然后提取一个可能的符号,然后是一个或多个数字。然后它将转换将该文本存储到int中,并将其存储在请求的位置。如果找不到合适格式的文本,它将设置错误状态(failbit),在清除之前将保持设置状态它不会修改i;你必须经常检查在使用变量input之前,input已成功。

另一方面,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,以便处理频带值CCD_ 14。int保证在范围内[0...UCHAR_MAX],或者是EOF,所以可以直接传递至CCD_ 18。只有当你完成这些测试后,你才应该将其转换为char(因为数字是字符)。

总是需要在读取后检查您的输入是否成功,例如

if (std::cin >> i) {
// process input
}

如果输入失败,则设置std::ios_failbit。当设置该标志时,流将不接受任何输入并转换为false。要清除错误标志,请使用

std::cin.clear();

清除错误标志不会删除有问题的字符。你需要去掉它们,例如,使用

std:: ignore();

上面的代码肯定不会创建一个无限循环。但循环通常发生在期望数字而给出非数字的情况下,因此缓冲区中的字符将停留在那里,流处于坏状态。这种情况会发生,直到流被适当地清除,以便stdio可以根据格式规范继续读取。当然,循环必须在我们的程序中完成,因为stdio本身并不是循环的。

要清除输入并恢复剩余内容,您可以使用以下方法:

std::cin.clear();
std::cin.ignore();
相关文章: