【问题标题】:My program goes into an infinite loop whenever I run it, but only whenever I enter an invalid number then a character or string每当我运行程序时,我的程序都会进入无限循环,但只有当我输入无效数字然后输入字符或字符串时
【发布时间】:2020-11-19 05:23:30
【问题描述】:

在我的程序中,我正在尝试验证用户输入并确保他们唯一可以输入的是 1998-2019 之间的数字。问题是,每当我先输入一个数字(并且只输入一个数字)时,程序运行良好,但如果我输入一个无效数字,然后输入一个字符或字符串,程序就会进入无限循环。每当我先输入字符或字符串然后输入数字时,该程序也会运行,但如果我在输入数字后输入字符,则会进入无限循环。有人知道为什么会发生这种情况或有可能的解决方案吗?

这是导致问题的代码:

   while (userInputYear < 1998 && userInputYear != -99 || userInputYear > 2019)
    {
        cout << "\nPlease enter an integer between 1998 and 2019: ";
    
        while (!(cin >> userInputYear)) 
        {
            cin.clear();
            cin.ignore(1000, '\n');
            cout << "\nPlease enter an integer between 1998 and 2019: ";
        }
    }

当我使用上面的代码时,显示的是这样的:

全国冠军查询

正在读取输入文件...

输入 1998 到 2019 之间的年份以查找冠军(按 -99 可 停止):2019

LSU Tigers 是 2019 年的全国冠军

输入 1998 到 2019 之间的年份以查找冠军(按 -99 可 停止):两千

请输入一个介于 1998 和 2019 之间的整数:请输入一个整数 1998 年至 2019 年间:-99

按任意键继续。 . .

这是我的整个程序:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;

class Champs
{
private:
    ifstream inChamps;      //input file

    int ayear[22];          //arrays
    string aname[22];

    int userInputYear = 0;              //holds value for user input


    void openFile();
    void testFile();
    void readFile();
    void validate();
    void yearName();
    void closeFile();

public:
    void driver()
    {
        openFile();
        readFile();
        yearName();
        closeFile();
    }
};

void Champs::openFile()                         //opens input file
{
    inChamps.open("NationalChampionship.txt");      
}

void Champs::readFile()
{
    if (inChamps.is_open())
    {
        cout << "National Championship Inquiry" << endl << endl;
        cout << "Reading the input file..." << endl << endl;
    }
    else
        testFile();
}

void Champs::testFile()
{
    cout << "Unable to open input file";
    exit(1);
}

void Champs::yearName()
{
    for (int i = 0; i < 22; i++)
    {
        int year;
        inChamps >> year;
        ayear[i] = year;

        string name;
        getline(inChamps >> ws, name);
        aname[i] = name;
    }

    

    //validate input
    
    bool on = true;
    while (on == true)
    {
        cout << "Enter the year: ";
        cin >> userInputYear;
        validate();
    
        if (userInputYear == -99)
            {
                on = false;
                break;
            }
        for (int i = 0; i < 22; i++)
        {
            
            if (userInputYear == ayear[i])
            {
                cout << "\nIn " << userInputYear << " the " << aname[i] << " won the national championship.\n\n";
            }
            
        }
    }
}

void Champs::validate()
{
    while (userInputYear < 1998 && userInputYear != -99 || userInputYear > 2019)
{
    cout << "\nPlease enter an integer between 1998 and 2019: ";

    while (!(cin >> userInputYear)) 
    {
        cin.clear();
        cin.ignore(1000, '\n');
        cout << "\nPlease enter an integer between 1998 and 2019: ";
    }
}

void Champs::closeFile()
{
    inChamps.close();
}

int main()
{
    Champs obj;
    obj.driver();
    system("pause");
    return 0;
}

我对 c++ 还是很陌生,但我觉得这是我所缺少的简单的东西。任何帮助或建议表示赞赏。还有,

【问题讨论】:

  • 读取 文本,然后将该文本放入 std::istringstream 并尝试从该字符串流中提取您需要的值。这样你就不会遇到无效输入仍然留在std::cin 的输入缓冲区中的任何问题(这是你现在遇到的问题)。
  • 首先它永远不会进入第一个while循环。其次,当您将字符读入整数时,会设置 cin 上的失败位。也就是说,您永远无法从流中读取数据,并且它总是会返回,因为它每次都会因无效输入而失败。因此是无限循环。

标签: c++ for-loop while-loop infinite-loop


【解决方案1】:

在第二个 while 循环中,您将进入无限循环,因为缓冲区中剩余无效字符。当 cin 遇到无效字符时,它会进入错误状态,发生这种情况时,您必须: 1.你必须测试这个错误状态。 2.您必须清除错误状态。 3. 您必须交替处理生成错误状态的输入数据,或者将其清除并重新提示用户。 像这样的东西我会更合适:

while (userInputYear < 1998 && userInputYear !=-99 || userInputYear > 2019)
    {
        cout << "Please enter an integer between 1998 and 2019: ";
        while(!(cin >> userInputYear)) {
          cin.clear();
          cin.ignore(1000, '\n');
          cout << "Please enter an integer between 1998 and 2019: ";
        }
        cout << endl;
    }

【讨论】:

  • 当我用它来防止无限循环时,我不再能够重复“请输入一个介于 1998 年和 2019 年之间的整数:”。我删除了第一个 while 循环,因为 user3389943 告诉我它永远不会通过那个循环。目前我只有你在 validate() 中修改的 while 语句。
  • 程序当前显示:`全国冠军查询正在读取输入文件...输入1998-2019之间的年份以查找冠军(按-99停止):abc 请输入介于之间的整数1998 年和 2019 年:abc'
  • 所以我使用了它,它仍然不成功。当我运行程序时,“请输入一个介于 1998 年和 2019 年之间的整数:”重复两次。然后我创建了另一个代码: while ((!(cin >> userInputYear)) && (userInputYear 2019)) { cin.clear(); cin.ignore(1000, '\n'); cout
  • 我编辑了我的原始问题,以便更清楚我的程序当前的样子。但我将原始代码留在了“完整程序”中。
  • 我觉得值得注意的是,在我更新的代码中,如果输入两次-99,程序就会结束。我觉得 !(cin>>userInputYear) 可能正在做一些奇怪的事情,但我不确定为什么或如何解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-15
  • 1970-01-01
  • 2021-06-17
  • 2019-07-17
相关资源
最近更新 更多