Sign in to follow this  
Joe Bob

continue, cin, and types - general C++ question

Recommended Posts

I'm working my way through C++ How To Program, and will hopefully (in the fullness of time) take my place among the ranks of you game-programming types. But first things first. Right now, I'm having trouble with the 'continue' statement (see code below). I would expect that right after the "Invalid entry." message, you'd immediately get another "Enter a number" prompt. But instead, if you a number not in the range 1 - 3, it works as expected. But if you enter something like a char, you get an endless loop of "Enter a number from 1 - 3 (0 to quit): Invalid entry. Try again." Why doesn't the program wait for you to enter a new value?
#include <iostream>

using std::cout;
using std::cin;
using std::endl;

int fun1(void);
int fun2(void);
int fun3(void);

int main(int argc, char *argv[])
{
        int (*f[3])(void) = { fun1, fun2, fun3 };

        int choice;

        while(true)
        {
                cout << "Enter a number from 1 - 3 (0 to quit): ";
                cin >> choice;

                if( choice < 0 ||  choice > 3 )
                {
                        cout << "Invalid entry.  Try again.\n";
                        choice=-1;
                        continue;
                }

                if(choice == 0) break;

                (*f[choice - 1])();
        }
        return 0;

}

int fun1(void)
{
        cout << "Function 1 is called!\n";
}
int fun2(void)
{
        cout << "Function 2 is called!!\n";
}
int fun3(void)
{
        cout << "Function 3 is called!!! You maniac!!!!\n";
}

Share this post


Link to post
Share on other sites
It doesn't wait because in case of a conversion error the input is left in the inputbuffer and the next call to cin >> choice will fail again.

You need something like:
if(cin >> choice)
{
//your code
} else {
cin.ignore();//dont know the parameters by heart
}

Share this post


Link to post
Share on other sites
Well your if statement should be && so that it tests for both conditions. About the endless loop its because cin is basically expecting you to enter a number if you enter a character that's not a number it fails. So you have to do a check for it, this should fix the problem.


if( cin.fail() )
{
cin.clear();
cin.ignore(256,'\n');
}



Share this post


Link to post
Share on other sites
[QUOTE]Well your if statement should be && so that it tests for both conditions.[/QUOTE]

It already does - doesn't it?

if( choice < 0 || choice > 3 )

My understanding is:

if choice is less than zero, the condition is met and it doesn't bother with second check. If choice is not less than zero, it checks to see if choice is greater than 3. If either condition is true, the condition is met.

Correct?

My new if works as I expected:

if( choice < 0 || choice > 3 )
{
cout << "Invalid entry. Try again.\n";
if( cin.fail() )
{
cin.clear();
cin.ignore(256,'\n');
}
continue;
}


Thanks alot!

Share this post


Link to post
Share on other sites
Quote:

if choice is less than zero, the condition is met and it doesn't bother with second check. If choice is not less than zero, it checks to see if choice is greater than 3. If either condition is true, the condition is met.


Nope, what it does is that it checks whether or not each condition given is true it doesn't just ignore everything else,you want the whole statement to be true ;). In other words if any of the two conditions you give are true then the if statement is true. Secondly you are wrong to believe that the conditions are evaluated in the order you write them to be sure you have to wrap the condition(s) you want evaluated first in a parentheses.

[Edited by - NullPointer33 on September 2, 2004 8:12:53 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by NullPointer33
Quote:

if choice is less than zero, the condition is met and it doesn't bother with second check. If choice is not less than zero, it checks to see if choice is greater than 3. If either condition is true, the condition is met.


Nope, what it does is that it checks whether or not each condition given is true it doesn't just ignore everything else,you want the whole statement to be true ;). In other words if any of the two conditions you give are true then the if statement is true. Secondly you are wrong to believe that the conditions are evaluated in the order you write them to be sure you have to wrap the condition(s) you want evaluated first in a parentheses.


His condition is correct; the condition is true if choise is outside the range [0, 3]. If you use && instead of ||, the condition will always evaluate to false, since the variable can't be less than zero and greater than three at the same time. It's enough for it to be either less than zero or greater than three to be an invalid number.

edit: Actually, the condition is not correct if you really look closer at what choise is actually used for. The condition should check whether it's in the range [1, 3], not [0, 3] as it does now. It should be

if(choice < 1 || choice > 3 )

Share this post


Link to post
Share on other sites
Quote:

His condition is correct; the condition is true if choise is outside the range [0, 3]. If you use && instead of ||, the condition will always evaluate to false, since the variable can't be less than zero and greater than three at the same time. It's enough for it to be either less than zero or greater than three to be an invalid number.



Oh, I was thinking that he wanted to do something else actually...that's what I get for not paying attention...I need some coffee now, I apologize for misleading you OP. [grin]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this