Need help to create a simple menu

Started by
9 comments, last by scuba4ever 15 years, 8 months ago
Hi. I'm having trouble with the following: "Rewrite the Menu Chooser program from this chapter using an enumeration to represent difficulty levels." The source: Download 1 The original "Menu Chooser" uses the switch() function with integer variable "choice", where it compares the cases with the inputted value stored in "choice". If there's a match, it outputs a corresponding message on the screen, if no match at all, the message "Invalid choice" pops up. But now I need to rewrite the program and use "enums" which will represent the difficulty levels. I tried figure out how would I program something like this, since Im not that strong with enums, and I kinda did but no luck - the VC++ 9 gives me an error. The source, with enums: Download 2 What am I doing wrong?
Advertisement
std::cin doesn't have a method of '<<' for the enumerator "difficulty".

Maybe instead try this?
enum difficulty {EASY, MEDIUM, HARD};difficulty myDifficulty;int input;int main(){     /*all that jazz here*/     cin << input;     myDifficulty = input;          switch(myDificulty)     {          case EASY:     /*You do the stuff*/     }return 0;}


Hope that helps. :]

~Maverick
Holy crap, you can read!
Thanks man, but it didn't quiet worked out for me.
When compiling in VC++ 9, I received this in Output-Build window:
Quote:
1>------ Build started: Project: menuchooserenum, Configuration: Debug Win32 ------
1>Compiling...
1>menuchooser.cpp
1>c:\documents and settings\ztein\my documents\visual studio

2008\projects\menuchooserenum\menuchooserenum\menuchooser.cpp(19) : error C2440: '=' : cannot convert from 'int'

to 'difficulty'
1> Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style

cast)
1>Build log was saved at "file://c:\Documents and Settings\User\My Documents\Visual Studio

2008\Projects\menuchooserenum\menuchooserenum\Debug\BuildLog.htm"
1>menuchooserenum - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========


Almost! But 1 error is on the way.

[Edited by - neshtak on July 26, 2008 7:48:35 PM]
Try rewriting line 19 as myDifficulty = (difficulty)input;
Oh It worked nicely! Thanks man.
But what does "myDifficulty = (difficulty)input;" means?

[Edited by - neshtak on July 26, 2008 7:04:05 PM]
It's a type cast.

For example:
/*We have a box that is 6 units wide and is divided up into 5 cells. We want to know the cell size*/ int box_size = 6;int box_cells = 5;float box_cell_size;int main(){     std::cout << "Box size is " << box_size <<" and has " << box_cells << " cells in it." << "\n";     std::cout << "What is the individual cell size? ...Calculating\n";     box_cell_size = box_size / box_cells;     std::cout << "Cell size is" << box_cell_size << "!\n";     return 0;}


Now, you'd think that box_cell_size would be [ 6/5 = ] 1.2, correct? Wrong. Since the variables being divided are both integers ( and integers cannot have decimal points ) box_cell_size ends up being "1" and we know this is incorrect.
Thankfully, the creators of the wonderful C++ language have a solution for this. There are many ranges of type-casting, but the one we will use here is the most common and simplest.

We need box_cell_size to equal to 1.2, so we're going to type-cast the integers for a moment to get this solution:
/*We have a box that is 6 units wide and is divided up into 5 cells. We want to know the cell size*/ int box_size = 6;int box_cells = 5;float box_cell_size;int main(){     std::cout << "Box size is " << box_size <<" and has " << box_cells << " cells in it." << "\n";     std::cout << "What is the individual cell size? ...Calculating\n";     box_cell_size = (float)box_size / (float)box_cells;     std::cout << "Cell size is" << box_cell_size << "!\n";     return 0;}


And the output is the correct "1.2".

So, you are pretty much doing the same thing. You've created enumerator called "difficulty" which the parts of it start from 0, to 1, n, until it comes to the last part of the enumerator. Since the assigned values to these parts of the enumerator is of the integer type, we type-cast the integer to be able to "understand" myDifficulty.
You could think of this as a language problem.
In spanish, "hello" is "hola". They both mean the same thing, but they're in different languages so both people would not understand what the other is saying, but if we "translate" it, they'll understand:
/*An english speaker and a spanish speaker cross paths. They both turn to say "hello" in they're language*/"hola" <-> "hello"/*They don't know what the other is saying at all, but both greetings mean the same thing. Let's help 'em*/"hola" <-> (spanish)"hello"/*we type casted or "translated" hello so both speakers understand one another. The same rule applies the other way.*/"hello" <-> (english)"hola"/*And it works!*/


^Please note the above was an example of type casting and is not necessarily psuedo-code or any working code for that matter.

I hope I helped any! If you need any other help, just ask me. :]

~Maverick
Holy crap, you can read!



Still the switch should probably have a 'default:' clause in it to handle incorrect input values (I forget if it can generate an exception if out of range values are applied to ENUMs... (with the right compiler option turned on))
--------------------------------------------[size="1"]Ratings are Opinion, not Fact
Whoah thanks, I got it now!
Quote:Original post by wodinoneeye



Still the switch should probably have a 'default:' clause in it to handle incorrect input values (I forget if it can generate an exception if out of range values are applied to ENUMs... (with the right compiler option turned on))


Wodinoneeye is right. For programming decency, make sure your switch statements have a "default" clause:
enum difficulty {EASY, MEDIUM, HARD};difficulty myDifficulty;int input;int main(){     /*all that jazz here*/     cin << input;     myDifficulty = (difficulty)input;          switch(myDificulty)     {          case EASY:     /*You do the stuff*/          break;     /*All the other cases*/          default:                cout << "That was not a level of difficulty. For your error, we'll set you on HARD. Mwaha.\n";                myDifficulty = HARD;          break;     }return 0;}


Thank Wodinoneeye for pointing that out. :]

~Maverick
Holy crap, you can read!
Firstly, it's cin >> input, not cin << input.

Second, there is nothing stopping you from defining an inserter for your enum so that you can cin directly into it. The syntax looks a bit overwhelming to a beginner but is pretty simple:

enum difficulty { EASY,MEDIUM,HARD,INVALID };std::istream &operator>>(std::istream &is,difficulty &d){    int i; is >> i;    switch(i)        {        case 0: d=EASY; break;        case 1: d=MEDIUM; break;        case 2: d=HARD; break;        default: d=INVALID;        }    return is;}


Now this is defined, your program can become a bit clearer:

int main(){     difficulty d;     std::cin >> d;          switch(d)     {          case EASY  : break;          case MEDIUM: break;          case HARD  : break;          default: d=HARD;     }}


Note that there is no point in having a break at the end of a default's code.

If you now decided to change it so the user actually typed "easy", "medium" or "hard", you only have to change the first inserter function and the change will propagate out to the rest of the program.

You could, of course, use a typecast from the int in the inserter function above, but by using the switch it constrains the difficulty variable to one of the four defined states regardless of what number is entered.

Obviously this is of limited improvement value in this simple program, but if you were inputting into a difficulty type in more than one place, the advantage becomes much clearer.

This topic is closed to new replies.

Advertisement