Sign in to follow this  

switch statement

This topic is 4484 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone! Just a quick question: (using c++ and visual studio 6.0, making text game) I have a menu that uses a switch statement to determine what the user wants to do in that menu. For example, the first line has a list of options (1. New Game, 2.Load game etc) It then waits for user input in the form of an integer. If the user puts in a character, it goes into infinite loop and I am trying to stop that. The default: portion of my switch statement is not protecting against this... What can I do?

Share this post


Link to post
Share on other sites
This problem actually has Nothing to do with Switch. see, when cin gets a bad input it goes into an error state which you can do a test against. This page seems like a very good explanation of the situation.

http://cplus.about.com/od/cprogrammingtip1/l/aa030702b.htm

Hope this helps.

Share this post


Link to post
Share on other sites
nobodynews is correct. Add in some of the code from the link he posted and you should be ok. Anytime you ask for user input, you should check the return value and handle exceptions.

Share this post


Link to post
Share on other sites
I was also thinking of casting the input into an integer when its in the switch statement

example

int choice;
cout << "Please enter your choice as an integer: \n";
cin >> choice;

switch(int(choice))
{
case 1:
//blabla
break;
......
default:
cout << "Invalid Choice";
}

would this work, or would cin still have the error flags going?


[edit - THANKS GUYS FOR THE QUICK HELP!! RATINGS ++]

Share this post


Link to post
Share on other sites
You can't cast a character directly into an integer the way you are doing it and expect it to work right. When you cast a char into an int, the int value returned is the integer ASCII value of that char. For example, casting the character 'a' into an int would give the integer value 65. To properly convert from a string (char) representation of a number into an actual number, you need to use the atoi(...) function (or atof if dealing with floats/doubles). See here for an explanation of the atoi function: http://www.cplusplus.com/ref/cstdlib/atoi.html.

Hope that helps.

Share this post


Link to post
Share on other sites
Slightly off-topic:
Try boost::lexical_cast.
Download boost here.
Using it, you can simply

std::string str = "123";
int i = boost::lexical_cast<int>( str );



int i = 123;
std::string str = boost::lexical_cast<std::string>( i );


If the cast fails, it throws a bad_lexical_cast exception.
Don't know if this works for MSVC6 (deprecated), so you might want to switch to Visual C++ 2005 Beta or Visual Studio 2003 Toolkit (free optimizing command line compiler, the one from Visual Studio .NET 2003), which have vastly better C++ standards conformance and work well with boost.

Share this post


Link to post
Share on other sites
thanks for the reply!
The reason why I'm not concerned with the atoi( function is because I want to test only for the case numbers. Anything else should be dealt with as an error.
My main objective was to try and cast the input into an int regardless and see if the cin error flags can be avoided.
I'm trying this right now I will reply shortly

Share this post


Link to post
Share on other sites
That should work then. I would suggest initializing your menu choice variable to something that is not a possible choice, since trying to read in a character or a string would essentially bypass assignment, so whatever was previously at the memory location used by the variable will be used.

Share this post


Link to post
Share on other sites
Ok, I tried using the if(!cin) and it works great. I also discovered that the default: section in the switch statement also works wonderfully with cin.ignore() and cin.clear.
Thanks to all with your help
I will however read up on the boost library.. thanks again

[edit- abso, thanks for the explanation, now i understand why my program was infinitely looping... because cin was being bypassed in my game loop. ++ ratings thanks guys]

Share this post


Link to post
Share on other sites
Make sure you get a value first, *then* try to use it (i.e. outside the input loop). One good idea is to make a function just for getting the value.


// This can be made a lot better, but is just for demonstration
int getAnActualNumber() {
int result;
cout << "give me a number" << endl;
while(!cin >> result) {
cin.clear(); // reset so that we can do more reading
cin.ignore(numeric_limits<int>::max, '\n'); // skip past the input that
// wasn't a number
cout << "no, I said a number!" << endl;
}
return result;
}

// later:
while (gameIsActive) {
switch(getAnActualNumber) {
// etc.



Note the effect that a failed read has. When you have "cin >> someInteger;", and the provided input doesn't match, the following happens:

1) No data is actually read.
2) someInteger is *not* changed. If it wasn't initialized before, it is still an uninitialized (garbage) value.
3) The stream has a flag set, which tells you that the read failed - but you also need to reset this flag before any more reading can happen.
4) Because no data was actually read, if you just reset the flag and try again in the same way, you'll fail again (by looking at the same data that doesn't work).

The "nothing is actually read" behaviour is intended, I can only guess, to let you try different interpretations of the input.

Share this post


Link to post
Share on other sites

This topic is 4484 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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