Reputation: 1
In my program, I am trying to validate the users input an make sure that the only thing they can put in is a number between 1998-2019. The problem is, whenever I input a number first(and only a number), the program runs fine but if I put an invalid number then a character or string, the program goes into an infinite loop. The program also runs whenever I type in a character or string first then a number, but if I type in a character after I have typed in a number, it enters an infinite loop. Does anybody know why this is occurring or have a possible solution?
This is the code causing the problem:
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: ";
}
}
When I use the above code this is what is displayed:
National Championship Inquiry
Reading the input file...
Enter a year between 1998 - 2019 to find the champion (press -99 to stop): 2019
The LSU Tigers were the National Champions in 2019
Enter a year between 1998 - 2019 to find the champion (press -99 to stop): two thousand
Please enter an integer between 1998 and 2019: Please enter an integer between 1998 and 2019: -99
Press any key to continue . . .
This is my entire program:
#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;
}
I am still very new to c++ but I feel like this is something simple I am missing. Any help or suggestions are appreciated. Also,
Upvotes: 0
Views: 102
Reputation: 129
In the second while loop, you are going to into the infinite loop because there are invalid characters left in the buffer. When cin encounters invalid characters it goes into an error state, when this happens you must: 1.You have to test for this error state. 2.You have to clear the error state. 3. You have to either alternatively handle the input data that generated the error state, or flush it out and reprompt the user. Something like this would me more appropriate:
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;
}
Upvotes: 2