# switch statement

## 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 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.

Hope this helps.

##### Share on other sites
What are you using to read user input?

##### Share on other sites
im using the cin >> function to get input
thanks!

##### 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 on other sites
I was also thinking of casting the input into an integer when its in the switch statement

example

int choice;
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 on other sites
I'm not sure. I usually just use the !cin method since that is what I was taught at school.

Try it and see if it breaks.

##### 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 on other sites
Slightly off-topic:
Try boost::lexical_cast.
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 on other sites
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 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 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 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 demonstrationint 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 on other sites
Quote:
 default:cout << "Invalid Choice";}

Try putting a break after the
default
like:
default:        cout <<"Invalid Choice";break;

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627654
• Total Posts
2978451

• 10
• 12
• 22
• 13
• 33