C++中的do-while无限循环与if语句

3

在这个循环中,用户应该输入一个int,如果它是奇数,程序将进入下一部分。但我不明白为什么如果用户输入的不是int字符,程序就会陷入无限循环!

int num;
do {
    cout << "PLEASE enter the num: ";
    cin >> num;
    if (num % 2 == 0)
        cout << "Number should be odd!" << endl;
    else
        break;
} while (true);
//...

因为无论如何 char/int != 0,如果它是==0,它也应该在下一个cin处停止,但它不会停止!我也尝试了ws(cin),但它没有帮助我。请告诉我如何解决这个问题,以及为什么会发生这种情况。


2
请参见此处 - LogicStuff
3个回答

4
由于您的程序没有检查cin >> num;的结果。由于cin >> num;(其中num是整数)将读取所有可用数字,如果输入根本不是数字[而不是空格字符,这些字符会被cin >>跳过],则它会不断尝试读取输入。
从您的问题中不清楚您想在用户向您的程序输入"askjhrgAERY8IWE"时做什么 - 有两个解决方案:
Alt 1. 删除错误的输入后再次询问。这可能适用于交互式应用程序,但对于从文件读取其输入的自动化程序来说是一个可怕的想法。
if(!(cin >> num))
{
     cout << "That deoesn't seem to be a number..." << endl;
     cin.clear();
     cin.ignore(10000, '\n');
}

备选方案2:以错误信息退出。当典型输入为数据文件时,这显然是正确的做法。

 if(!(cin >> num))
 {
      cout << "That deoesn't seem to be a number..." << endl;
      exit(1); 
 }

您还需要在此代码中添加处理文件末尾的代码-对于文件输入,这应该是可以接受的(除非该文件具有特定的数据来标记结尾)。对于交互式输入(用户直接向程序键入),文件结束可能会被视为错误或不是错误-这实际上取决于接下来会发生什么。

我认为你在回答的结尾不小心漏掉了一些单词。 - BoBTFish
@BoBTFish:谢谢,通常是“过早发布”。 - Mats Petersson
我尝试了你告诉我的,但是当我输入“abcd”时,“!cin >> num”并不为“True”。 - Danial Razavi
@DanialRazavi:啊,我错过了几个括号 - 应该是 if (!(cin >> num)) - 我还错过了必需的 cin.clear();cin.ignore() 之前 - 这会清除 cin 当输入不是有效数字时进入的错误状态,而在错误状态下,将不接受任何进一步的输入,因此它会一直打印“错误”。 - Mats Petersson
@MatsPetersson 我不明白为什么当我输入数字时,条件的值不会是 False,但当我输入非数字时,它却变成了 True - Danial Razavi
显示剩余3条评论

0
在你的程序中,标准输入流期望一个整数。当你给它一个字符时,cin无法将其放入整数变量中,即它失败了(错误标志被设置),并将输入的字符留在缓冲区中(供下一个cin赋值使用)。cin会反复将该字符视为输入并继续失败,而整数变量则被赋予值0。
为了防止这种情况发生,你可以修改你的程序如下:
int num;
    do{
        cout << "PLEASE enter the num: ";
        while(!(cin>>num)){
        cin.clear();
        cin.ignore(INT_MAX,'\n');
        cout<<"Invalid. Enter a number";
    }
        if (num % 2 == 0)
            cout << "Number should be odd!" << endl;
        else
            break;
    }
while(true);

包含 limits.h 以使用 INT_MAX,或者您可以使用像 10000 这样的大值。

cin.clear 清除错误标志并准备好接受输入。 cin.ignore(INT_MAX,'\n') 忽略一切(最多 INT_MAX 个字符),直到下一个换行符。这确保了如果用户输入了一行长字符串而不是数字,程序也能正常工作。


那样做没有帮助,因为如果用户输入 1abc,程序将接受它并通过循环,但我需要只有在输入是数字和奇数时才能通过循环。 - Danial Razavi

0
我找到了解决问题的方法,我将输入类型更改为string并编写以下函数:
int isNum(string input)
{
    int digit, value = 0;
    for (int i = 0; i < input.length(); i++)
    {
        digit = input[i] - '0';
        if (digit >= 0 && digit <= 9)
            value = value * 10 + digit;
        else
        {
            value = 0;
            break;
        }
    }
    return value;
}

如果所有字符都在0到9之间,它将返回输入作为int,否则它将return 0;给我,因此我使用返回的int作为我的num


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接