When I run my program it ignores the cin and goes into an infinite loop. It acts as though the cin.ignore() isn't working.

int getInput(int tries){
    int numGuess = 0;
    cin >> numGuess;
    cin.ignore();
    validate(numGuess, tries);
    return 0;
}

int validate (int input, int tries){

    if (input <1 || input >100){
        cout << "Please enter a decimal integer between 1 and 100: ";

        getInput(tries);
    }
    return NULL;
}

Recommended Answers

All 14 Replies

While I am not certain why it appears to be bypassing the input, I can tell you why it is going into an infinite loop: at no point do you change or test tries , which means that if the input is not a valid number in the right range, it will keep calling getInput() recursively until the stack runs out.

I could add that you do not as of this code check the return value of validate() , and getInput() always returns zero. I suspect you intended something more like this:

int getInput(int tries){
    int numGuess = 0;
    cin >> numGuess;
    cin.ignore();
    return validate(numGuess, tries);
}

int validate (int input, int tries){

    if (input < 1 || input > 100){
        cout << "Please enter a decimal integer between 1 and 100: ";
        tries--;
        if (tries <= 0)
            return 0;
        else 
            return getInput(tries);
    }
    else
        return input;
}

Correct. tries is changed in another function. If the user does not input a valid number it will ask for another number until a valid number is inputted, i.e. an infinite loop by design. Also both the return values are checked elsewhere as well.

Correct. tries is changed in another function. If the user does not input a valid number it will ask for another number until a valid number is inputted, i.e. an infinite loop by design.

Yes, but the other function would never be called in this code as it is, thus the loop could not be broken.

Could you post this other code, so we can see what's going on in the big picture?

Also both the return values are checked elsewhere as well.

That may be, but if they always return the same value (zero in both cases), then what is there to be checked?

You should insert a argument for cin.ignore() so that it works, or flushes out the stream....

This is the full code. If the program doesnt restart after a bad input, the program runs fine, but it has to restart.

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

int check (int numOne, int tries, int numGuess);
bool validate (int input);
int getInput();

int main (){
    srand(time(0));
    int numOne = (rand()%100) + 1; //seed computer's number
    int tries = 0;
    int input;
    cout << numOne << endl; // used for checking program.

    cout << "I have a decimal integer between 1 and 100." << endl << "Can you guess it? ";
    input = getInput();
    while(validate(input)){   //while number is valid (1-100)
        check(numOne, tries, input); //continue with program
    }
    cout << "Error, Enter an integer."; //else restart program
    main();

    return NULL;
}

int getInput(){    //get users number guess
    int numGuess = 0;
    cin >> numGuess;
    cin.ignore();
    return numGuess;
}

bool validate (int input){

    if (input <1 || input >100){
        cout << "Please enter a decimal integer between 1 and 100: ";
    }
    return NULL;
}
int check (int numOne, int tries, int numGuess){

    tries++;
    for(int i = 0; i < 9; i++){

    if (numGuess > numOne) {
        cout << "Too high, Try again! ";
        check(numOne, tries, numGuess);
        } else if (numGuess < numOne) {
            cout << "Too low, Try again! ";
            check(numOne, tries, numGuess);
        } else {
            cout << "You guessed it! " << "It only took you " << tries << " tries!" << endl;
			break;
        }
    }
    cout << "If you would like to play again, enter 1 ";
	int temp;
	cin >> temp;
	cin.ignore();
    if (temp == 1){
        main();
    }
    return NULL;
}

As much as I personally like recursive approaches, recursing on main() is generally considered a Bad Thing. The main() function is different from others; while it is possible to call it, doing so is problematic. A more conventional approach would be:

int main (){
    char yesNo = 'Y';
    srand(time(0));

    while(toupper(yesNo) == 'Y') 
    {
        int numOne = (rand()%100) + 1; //seed computer's number
        int tries = 0;
        int input;
        cout << numOne << endl; // used for checking program.

        cout << "I have a decimal integer between 1 and 100." << endl << "Can you guess it? ";
        input = getInput();
        while(validate(input)){   //while number is valid (1-100)
             check(numOne, tries, input); //continue with program
        }
        cout << "Continue (Y/N)? ";
        cin >> yesNo;
        cin.ignore();
     }

    return 0;
}

I could add that validate() is still problematic; it is declared as type bool , but returns NULL rather than either true or false , and the result doesn't vary. The sum effect of this is that the line

while(validate(input)){

always evaluates as false, meaning that the program never enters the loop in the first place.

Thanks for all the help guys. The problem with that is after a user inputs a valid number and presses enter, it is passed to the validate function to validate. If it validates as true, then the check function is run in an infinite loop.

while(validate(input)){ //while number is valid (1-100)
    check(numOne, tries, input); //continue with program
}

The break located in the check function only breaks the for loop.

for(int i = 0; i < 9; i++){

		if (numGuess > numOne){
			cout << "Too high, Try again! ";
			numGuess = getInput();
			check(numOne, tries, numGuess);
		} else if (numGuess < numOne) {
			cout << "Too low, Try again! ";
			numGuess = getInput();
			check(numOne, tries, numGuess);
		} else {
			cout << "You guessed it! It only took you " << tries << " tries!" << endl;
			break;
		}
		break;
	}

Even if that was implemented, the cin >> numGuess; is still ignored. What I ended up doing was using a string and converting it to an integer with

string tempString;
    cin >> tempString;
    cin.ignore();
    int numCont = atoi(tempString.c_str());

That seems to work well and I was having problems with the code in other areas so I completely started over and now I have the following code which I can't find any bugs in

#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
using namespace std;

int check (int numOne, int tries, int numGuess);
bool valid (int input);
int getInput();

int main(){
	srand(time(0));
	int numOne = (rand()%100) + 1;
	int tries = 0;
	int input = 0;
	cout << numOne << endl; // used for checking program

	cout << "I have a decimal integer between 1 and 100." << endl << "Can you guess it? ";

	input = getInput();
	check(numOne, tries, input);

	return NULL;
}

int getInput(){
	string tempString;
	cin >> tempString;
	cin.ignore();
	int numGuess = atoi(tempString.c_str());

	if (valid(numGuess) == true){
		return numGuess;
	} else {
		numGuess = getInput();
	}
	return numGuess;
}

bool valid(int input){

	if (input < 1 || input > 100){
		cout << "Error, please enter a decimal integer between 1 and 100: ";

		return false;
	}

	return true;
}

int check (int numOne, int tries, int numGuess){
	tries++;
	for(int i = 0; i < 9; i++){

		if (numGuess > numOne){
			cout << "Too high, Try again! ";
			numGuess = getInput();
			check(numOne, tries, numGuess);
		} else if (numGuess < numOne) {
			cout << "Too low, Try again! ";
			numGuess = getInput();
			check(numOne, tries, numGuess);
		} else {
			cout << "You guessed it! It only took you " << tries << " tries!" << endl;
			break;
		}
		break;
	}

	cout << "If you would like to play again, enter 1 ";

	string tempString;
	cin >> tempString;
	cin.ignore();
	int numCont = atoi(tempString.c_str());
	if (numCont == 1){
		main();
	}
	exit(0);
	return NULL;
}

It would still be nice to figure out why the cin >> numGuess; was being ignored even with the cin.ignore(); after it.

Try the following code:

#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;

bool check (int numOne, int tries, int numGuess);
bool validate (int input);
int getInput();

int main ()
{
    int tries, input;
    char yesNo = 'Y';
    srand(time(0));

    while(toupper(yesNo) == 'Y')
    {
        int numOne = (rand()%100) + 1; //seed computer's number
        tries = 0;
        input = 101;

        cout << "I have a decimal integer between 1 and 100." << endl << "Can you guess it? ";

        do
        {
            do
            {
                input = getInput();
            }
            while (!validate(input));

            tries++;
        }
        while ((tries < 9) && !(check(numOne, tries, input)));

        if (tries == 9)
            cout << "Sorry, you ran out of guesses." << endl << endl;

        cout << "Play again (Y/N)? ";
        cin >> yesNo;
        cin.ignore();
    }

    return 0;
}

int getInput()     //get users number guess
{
    int numGuess = 0;
    cin >> numGuess;
    cin.ignore();
    return numGuess;
}

bool validate (int input)
{
    if (input < 1 || input > 100)
    {
        cout << "Please enter a decimal integer between 1 and 100: ";
        return false;
    }
    return true;
}

bool check (int numOne, int tries, int numGuess)
{

    if (numGuess > numOne)
    {
        cout << "Too high, Try again! " << endl;
        return false;
    }
    else if (numGuess < numOne)
    {
        cout << "Too low, Try again! " << endl;
        return false;
    }
    else
    {
        cout << "You guessed it! " << "It only took you " << tries << " tries!" << endl;
        return true;
    }

}

That works great except for one thing. If the user enters a letter, string, or a super long number, it goes into an infinite loop again, as if ignoring the cin.ignore();

OK, this code here should solve that issue:

int getInput()     //get user's number guess
{
    int numGuess = 0;
    while (numGuess == 0)
    {
        cin >> numGuess;
        if (cin.fail())
        {
            cout << "Please enter a number: ";
        }
        cin.clear();
        cin.ignore();
    }

    return numGuess;
}

Works great except for one thing. when numGuess is set to 0 and when you enter the while loop, you ask for input. If the user inputs 0, it proceeds and then cin.fail() doesnt fail because 0 is a valid int . It proceeds to cin.clear() and cin.ignore() then continues in the loop until a number in range is entered. I think with the following it will work.

int getInput(){ //get users number guess

        int numGuess = 0;

        while(numGuess == 0){
            cin >> numGuess;
            if (numGuess < 1 || numGuess > 100 || cin.fail()){
                numGuess = 0;
                cout << "Enter a number between 1 and 100 ";
            }
            cin.clear();
            cin.ignore();
        }

        return numGuess;
    }

It would still be nice to figure out why it wasnt working. Maybe the cin fail state was set so it ignored any following cin because it thought it was failed?

Please, guys (Schoil-R-LEA and kjcjk), stop writing the code for people. They need to figure it out, we should point the way, but not fix the code.

I'll admit that I've probably gone too far.

Kjcjk, however, is the OP, so he has reason to be posting the code he's trying to fix.

Ahhh, 2nd page. Lack of info... sorry.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.