58

I would like to use an enum value for a switch statement. Is it possible to use the enum values enclosed in "{}" as choices for the switch()"?

I know that switch() needs an integer value in order to direct the flow of programming to the appropriate case number. If this is the case, do I just make a variable for each constant in the enum statement?

I also want the user to be able to pick the choice and pass that choice to the switch() statement.

For example:

cout << "1 - Easy, "; cout << "2 - Medium, "; cout << "3 - Hard: "; enum myChoice { EASY = 1, MEDIUM = 2, HARD = 3 }; cin >> ???? switch(????) { case 1/EASY: // (can I just type case EASY?) cout << "You picked easy!"; break; case 2/MEDIUM: cout << "You picked medium!"; break; case 3/HARD: // ..... (the same thing as case 2 except on hard.) default: return 0; } 
2
  • 4
    All of those cases == 1. Commented Jun 10, 2010 at 23:07
  • 12
    @Noah: I believe he's using a slash to indicate "one or the other", not division. While mathematically you're correct, I don't believe that is the actual code he intends to use. Commented Jun 11, 2010 at 0:16

9 Answers 9

50

You can use an enumerated value just like an integer:

myChoice c; ... switch( c ) { case EASY: DoStuff(); break; case MEDIUM: ... } 
Sign up to request clarification or add additional context in comments.

Comments

24

You're on the right track. You may read the user input into an integer and switch on that:

enum Choice { EASY = 1, MEDIUM = 2, HARD = 3 }; int i = -1; // ...<present the user with a menu>... cin >> i; switch(i) { case EASY: cout << "Easy\n"; break; case MEDIUM: cout << "Medium\n"; break; case HARD: cout << "Hard\n"; break; default: cout << "Invalid Selection\n"; break; } 

5 Comments

Should probably initialise i to a value that will hit the default case, though, or a value interpreted as I/O error.
typedef enum e { ... }; ?? The typedef is optional in C++ but if present, there should be a typedef-ed name after the closing brace. Also, in C++ (as compared to C) you should use the enum type and not int for the variable (even if the compiler will gladly take int).
@David: typedef error was definitely not standard form. Fixed. I chose not to declare the input as 'Choice' because that makes the input stream operator '>>' ambiguous.
Ok on the type of the variable, but still is more C++ like to have: enum Choice { EASY = 1, MEDIUM = 2, HARD = 3 }; rather than having a typedef of an unnamed enum.
I guess that's something I picked up from an old mentor and never had a reason to change. Updated in the answer.
18

Some things to note:

You should always declare your enum inside a namespace as enums are not proper namespaces and you will be tempted to use them like one.

Always have a break at the end of each switch clause execution will continue downwards to the end otherwise.

Always include the default: case in your switch.

Use variables of enum type to hold enum values for clarity.

see here for a discussion of the correct use of enums in C++.

This is what you want to do.

namespace choices { enum myChoice { EASY = 1 , MEDIUM = 2, HARD = 3 }; } int main(int c, char** argv) { choices::myChoice enumVar; cin >> enumVar; switch (enumVar) { case choices::EASY: { // do stuff break; } case choices::MEDIUM: { // do stuff break; } default: { // is likely to be an error } }; } 

6 Comments

In order for this to work you would need to overload the istream operator>> for the enumeration.
+1 overall, but I disagree in the always provide a default: case. I understand that the intention is triggering a known error so that it can be easily corrected if a new enumerated value is later added to the enumeration. I prefer actually processing the input to guarantee the correctness of the user data, and not providing a default tag, but rather having the compiler warn about switch statements if there is any value that falls outside of all tested cases. This way you get an even faster error report: the compiler will complain if a value is added to the enumeration.
Also you probably need to initialise enumVar. This code yields undefined behavior if cin >> enumVar doesn't write a value, which is typically the case when operator>> encounters an error. As James says, though, you'll be overloading the operator for the enum anyway, so you could write it to always assign something even on error.
good comments and suggestions, that'll learn me to post a code solution without compiling it first :P
Disagree about the "always have a break...". Sometimes you want to use the trick of "fall-through". And also disagree about the "always include the default...". You can previously validate your input prior to the switch statement.
|
8

You can use a std::map to map the input to your enum:

#include <iostream> #include <string> #include <map> using namespace std; enum level {easy, medium, hard}; map<string, level> levels; void register_levels() { levels["easy"] = easy; levels["medium"] = medium; levels["hard"] = hard; } int main() { register_levels(); string input; cin >> input; switch( levels[input] ) { case easy: cout << "easy!"; break; case medium: cout << "medium!"; break; case hard: cout << "hard!"; break; } } 

3 Comments

This will return easy if the string does not match any of the valid choices.
I like this approach as it allows the user to input descriptive strings, not integers. A small thing, but I would use an unordered map for something with so few possible values. Map (binary tree) is interesting because if there were hundreds or thousands of values a map would be more efficient than switch:case, only having to do O(log N) compares, vs N/2.
this is overdue , but in your enum set the values equal to integers starting from 1. 0 defaults to no case. so , enum levels = {EASY=1,MEDIUM=2,HARD=3};
3

I had a similar issue using enum with switch cases.

Later, I resolved it on my own....below is the corrected code, and perhaps this might help.

//Menu Chooser Programme using enum #include <iostream> using namespace std; int main() { enum level{Novice=1, Easy, Medium, Hard}; level diffLevel = Novice; int i; cout << "\nEnter a level: "; cin >> i; switch(i) { case Novice: cout << "\nyou picked Novice\n"; break; case Easy: cout << "\nyou picked Easy\n"; break; case Medium: cout << "\nyou picked Medium\n"; break; case Hard: cout << "\nyou picked Hard\n"; break; default: cout << "\nwrong input!!!\n"; break; } return 0; } 

Comments

3

You should keep in mind that if you are accessing a class-wide enum from another function, even if it is a friend, you need to provide values with a class name:

class PlayingCard { private: enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }; int rank; Suit suit; friend std::ostream& operator<< (std::ostream& os, const PlayingCard &pc); }; std::ostream& operator<< (std::ostream& os, const PlayingCard &pc) { // Output the rank ... switch(pc.suit) { case PlayingCard::HEARTS: os << 'h'; break; case PlayingCard::DIAMONDS: os << 'd'; break; case PlayingCard::CLUBS: os << 'c'; break; case PlayingCard::SPADES: os << 's'; break; } return os; } 

Note how it is PlayingCard::HEARTS and not just HEARTS.

Comments

0

The user's input will always be given to you in the form of a string of characters... if you want to convert the user's input from a string to an integer, you'll need to supply the code to do that. If the user types in a number (e.g. "1"), you can pass the string to atoi() to get the integer corresponding to the string. If the user types in an english string (e.g. "EASY") then you'll need to check for that string (e.g. with strcmp()) and assign the appropriate integer value to your variable based on which check matches. Once you have an integer value that was derived from the user's input string, you can pass it into the switch() statement as usual.

1 Comment

The code to convert the input from a string to an integer is int i; cin >> i;. This isn't C, so there's no need to mess around with the C library.
0
#include <iostream> using namespace std; int main() { enum level {EASY = 1, NORMAL, HARD}; // Present menu int choice; cout << "Choose your level:\n\n"; cout << "1 - Easy.\n"; cout << "2 - Normal.\n"; cout << "3 - Hard.\n\n"; cout << "Choice --> "; cin >> choice; cout << endl; switch (choice) { case EASY: cout << "You chose Easy.\n"; break; case NORMAL: cout << "You chose Normal.\n"; break; case HARD: cout << "You chose Hard.\n"; break; default: cout << "Invalid choice.\n"; } return 0; } 

Comments

-1

You can cast enum with int.

enum TYPE { one, two, tree }; TYPE u; u = two; switch( int( u ) ){ case one : action = do_something ; break; case two: action = do_something_else; break; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.