I've written a program for my C++ class and I ran into a little problem which I'm not quite sure how to solve. Some of you may be familiar with this textbook exercise as I've seen questions asked about it on the site before, but I was unable to find any simple fix.
I have to create a class which is used to store information about a pizza. I've got the program written and functional, but I need the class call to loop through a series of iterations based on the user's input. I know that this can be achieved using vectors, something we haven't hit yet in the semester, but will get to soon enough I'm sure. Is there a way to do this without vectors?
Here's the class.
class Pizza
{
private:
int type;
int size;
int numCheeseTopping;
int numPepperoniTopping;
bool cheeseTopping;
bool pepperoniTopping;
public:
Pizza();
int getType();
int getSize();
bool getCheese();
bool getPepperoni();
void setType(int t);
void setSize(int s);
void setCheese(bool choice, int temp);
void setPepperoni(bool choice, int temp);
void outputDescription();
double computePrice();
void outputPrice();
};
And the constructor.
Pizza::Pizza()
{
// Set initial class values
type = DEEPDISH;
size = SMALL;
cheeseTopping = false;
numCheeseTopping = 0;
pepperoniTopping = false;
numPepperoniTopping = 0;
}
Main is only two functions.
// Main function
int main()
{
// Call global functions
welcomeMsg();
buildPizza();
return 0;
}
I have a feeling that my problem lies in the buildPizza function, as it calls other functions as well as creating the objects. Here it is...
void buildPizza()
{
char pType, pSize, tempCheese, tempPepperoni;
int type = 0, size = 0, numCheeseTopping = 0, numPepperoniTopping = 0;
// Ask user what size pizza they would like.
cout << "What size pizza would you like?" << endl;
cout << "\tS: Small" << endl;
cout << "\tM: Medium" << endl;
cout << "\tL: Large" << endl;
cout << "Size: ";
cin >> pSize;
// Determine which size the user input and convert the
// result.
switch (pSize)
{
case 'S':
case 's':
size = SMALL;
break;
case 'M':
case 'm':
size = MEDIUM;
break;
case 'L':
case 'l':
size = LARGE;
break;
}
// Ask the user which type of pizza they would like.
cout << endl << "What type pizza would you like?" << endl;
cout << "\tD: Deepdish" << endl;
cout << "\tH: Hand-Tossed" << endl;
cout << "\tP: Pan" << endl;
cout << "Type: ";
cin >> pType;
// Determine which type the user input and convert the
// result.
switch (pType)
{
case 'D':
case 'd':
type = DEEPDISH;
break;
case 'H':
case 'h':
type = HANDTOSSED;
break;
case 'P':
case 'p':
type = PAN;
break;
}
// Call Pizza Class.
Pizza myPizza;
// Call Pizza Class functions.
myPizza.setSize(size);
myPizza.setType(type);
// Ask user whether they want cheese or not.
cout << endl << "Would you like cheese (y/n)? ";
cin >> tempCheese;
// If so call setCheese.
if (tempCheese == 'Y' || tempCheese == 'y')
{
cout << "How many cheese toppings would you like? ";
cin >> numCheeseTopping;
myPizza.setCheese(true, numCheeseTopping);
}
// Ask user whether they want pepperoni or not.
cout << endl << "Would you like pepperoni (y/n)? ";
cin >> tempPepperoni;
// If so call setPepperoni.
if (tempPepperoni == 'Y' || tempPepperoni == 'y')
{
cout << "How many pepperoni toppings would you like? ";
cin >> numPepperoniTopping;
myPizza.setPepperoni(true, numPepperoniTopping);
}
// Call outputDescription to give user an overview
// of their order.
cout << endl << endl;
myPizza.outputDescription();
cout << endl;
// Compute the cost of the pizza and display it.
myPizza.outputPrice();
}
Basically, I'd like the program to ask the user how many pizzas they would like to evaluate, create that many class iterations, then cycle through 'building' or 'ordering' each pizza, then display a total and return 0.
As I look at the code now I can take the last two function calls out of buildPizza and move the calls into main, but this will not solve my problem. Only an oversight I literally just noticed within the program.
Is there an easy way to create, say, 200 new objects all at once at runtime. Each one with a different name? Should I just pick a number to evaluate and force the user to enter information for that many objects? Right now, the program evaluates one pizza and quits.
I'd like something like this to happen:
User asks program to create a 5 pizza order.
Program creates 5 pizza objects.
Program iterates through each object getting and setting information for each one.
Program displays some stuff and returns 0.
Is this possible with my code, or do I need to consider a rewrite? Any guidance the community can give me will be immensely helpful.
Thanks.
Kyle
Since you cnanot use arrays or vectors, a simple for would suffice.
auto nrPizzas = getNumberOfPizzasFromUserInput();
for(int i = 0; i < nrPizzas; i++) {
auto pizza = Pizza{};
// do your stuff here.
output to the screen here();
}
You can prompt for the number of pizzas user want and then create a dynamic array of that much pizzas and then iterate through their build function or else you can make a linked-list with struct type of pizza and then rewrite the main logic. Second approach is advised if you do not want to prompt that how many pizza's the user wants to order.
Related
This program I came across on another forum is a voting program, someone was having issues with compiling. Any answer that was given didn't really match up with what the programmer wanted. So I am here to get some effective answers after attempting to edit the code myself.
The current issue I am having is when I input the variable, it still runs an infinite loop. What am I not doing properly for the design to perform, until I input 5 votes?
#include <iostream>
using namespace std;
const int ev = 5; //max. # of votes
int votesA = 0, votesB = 0, votesC = 0, spoiltvotes = 0; //total votes already initialized globally
int vote; //input variable
int main()
{
//loop over the voting stations
int i;
for(i = 0; i <= ev; i++)
{
//loop over the votes
cout << "Enter your vote: \t";
cin >> vote;
while(vote <= 5)
{
switch(vote)
{
case 1: votesA++;
break;
case 2: votesB++;
break;
case 3: votesC++;
break;
default: spoiltvotes++;
}
}
}
//display results neatly
cout << "# of votes for candidate A: \t" << votesA;
cout << "\n # of votes for candidate B: \t" << votesB;
cout << "\n # of votes for candidate C: \t" << votesC;
cout << "\n # of spoilt votes: \t" << spoiltvotes;
return 0;
}
Updated Result: I have fixed the infinite loop but for some reason the loop is still iterating 6 times instead of 5, giving me large tallies of numbers instead of single-digits.
#include <iostream>
using namespace std;
int main()
{
const int ENDvote = 5; //max. # of votes
//loop over the voting stations
int vote;
int spoiltvotes;
for(vote = 0; vote >= ENDvote; vote++)
cout << "1. Candidate A\t 2. Candidate B\t 3. Candidate C" << endl;
{
//loop over the votes
cout << "Enter your vote: \t";
cin >> vote;
switch(vote)
{
case 1:
cout << "# of votes for candidate A:\t" << vote;
break;
case 2:
cout << "# of votes for candidate B:\t" << vote;
break;
case 3:
cout << "# of votes for candidate C:\t" << vote;
break;
default:
cout << "# of spoilt votes:\t" << spoiltvotes;
break;
}
}
return 0;
}
There is an obvious issue to your code.
When you enter your for loop : ‘for(i = 0; i <= ev; i++)’ you get to the ‘cin>>vote;’ When you get the vote if ‘vote<=5’ the loop with go on forever due to the while loop. Once you enter the while loop VOTE NEVER CHANGES. So, if the while loop condition is fulfilled, it will always be true since(again) vote doesn’t change.
Fred Larson said what I am saying essentially.
I am new to stack overflow so anything you think I should be doing, please tell me.
Others have already commented on what's the problem with your program, the while loop would never break since vote is never getting updated and if the input value in vote is <=5, it shall remain to be so and end up being an infinite while loop.
A while loop within a for loop is usually not something you'd want and should look hard at the code and see if that's what you really want. If not, refactor it out to stick with either one of them, not both.
Your problem appears to be in a similar vein. From your program, it seems that you want to read in the votes polled at the 5 voting stations and then count the number of votes that each candidate received (or went waste).
If you go the for loop route, you just need to iterate over the loop, read in the number of votes (alongwith input validations), do the switch case and then move on to the next iteration of the for loop.
If you go the while loop route, then just have a while loop to read in five votes, something like
while(std::cin>>vote) {
switch(...
and do pretty much the same stuff.
Also, global variables are (again) usually a bad idea, especially if they are non-const. Move them into your main().
Also, do take care that a break statement only breaks the inner-most loop. So, doing something like
while(true) {
int x = 1;
switch(x) {
case 1:
break;
}
}
will not break the while loop,.
This is my first time on this web site. I have been having a problem but I haven`t been able to figure it out. I have been trying to implement a predefined function into my code but I am not sure how to do so. In my Task I was given an open brief asking me simply to design a password protected calculator. I designed the calculator and handed it in to my teacher. He then asked me to add a predefined function. Now I am not sure how to do this or even how I would start. Could any one give me some example of a predefined function similar to my code.
#include <iostream>
using namespace std;
int main()
{
char op;
float num1, num2;
int correct_password = 1998;
int password = 0;
int counter = 0;
int attempt = 0;
while (attempt <= 3) {
cout << "Enter your password: ";
cin >> password;
attempt = attempt + 1;
if (password != correct_password) {
cout << "Incorrect password combination. Please try again." << "\n" << endl;
} else {
break;
}
}
if (attempt >= 3) {
return 0;
}
cout << "Access granted." << endl;
//Asks you to enter an operator to use in your calculation
cout << "Enter operator either + or - or * or /: ";
cin >> op;
//Asks you to enter 2 numbers
cout << "Enter two operands: ";
cin >> num1 >> num2;
//Searches for which operator you have selected and Either *-+/ the number depending on choice
switch (op) {
case '+':
cout << num1 + num2;
break;
case '-':
cout << num1 - num2;
break;
case '*':
cout << num1 * num2;
break;
case '/':
cout << num1 / num2;
break;
//If entered operator is incorrect closes down the program
default:
cout << "Error! operator is not correct";
break;
}
return 0;
}
Sorry for the trouble. I am not quite sure if I am going about asking this the right way. so I will apologies before hand if I am not specific enough or if I am doing ti wrong :).
(edit:: added some explanation)
I can't know what exactly your teacher wanted, but it might be something like this:
void foo(float a, float b){
return a+4*b;
}
Allowing your calculator to use a function like that would work in the following way:
... //Your previous code here
switch(op){
... // Your other switches here
case 'f':
cout<<foo(num1,num2)<<endl;
break;
}
... //Your following code here
The 'f' here stands for the command "EXECUTE PREDEFINED FUNCTION" instead of '+' for "ADD" or '-' for "SUBTRACT".
That way you could have a predefined function and execute that on your numbers.
In this case we would see the entred number num1 be added to four times the entered number num2
I hope it helped :)
these function are in library #include<math.h> You need to use this header file in order to use those function in your code .
It includes predefined functions such as
sqrt(number);
This function is used to find square root of the argument passed to this function.
pow(number);
This is used to find the power of the given number.
trunc(number);
This function truncates the decimal value from floating point value and returns integer value
The purpose of the program is a bank account interface, where the user can create 4 accounts and can transfer funds between them. I opted for an array of structs to handle the “bank account” info, and a switch to handle the user options.
Problem:
The account creation function, called in case ‘a’, appears to create the accounts as intended, and displays them properly. However, the results in the other cases are not as designed.
Case ‘b’ will display the inputted array information, only if nothing is called (including the function that displays the array information), otherwise when the display() is called it prints zeros (what it is initialized to before account creation).
Case ‘c’ will display the inputted array information if nothing is called, as well as if only the function which displays the date/time is called. Otherwise it prints zeros.
Question:
Why is the array of structs displaying zeros when I call the display function, but will display the user input when it’s not called, as long as nothing else is (except the time function in case ‘c’), and what can I do to fix it?
Notes:
I converted the account creation function to return a pointer to the struct hoping that might help, it didn’t seem to change anything. I converted the switch statement to a series of if’s to see if that would change anything, it did not (reversed back to switch). Case ‘d’ and case default work as intended. The Program is not complete (my transfer() isn’t written). I’m aware “using namespace std;” is a nono.
I appreciate your time and any advice offered.
#include <iostream>
#include <ctime>
const int SIZE = 4;
using namespace std;
struct bank //Bank Account Structure to hold account numbers and balances
{
int num; // number of account
int checkdigit; // ending account number checkdigit appended to account number
float bal; // balance of account
};
void menu(); //MenuPrompt
bank* input(bank[]); // Struct Account Input
void display(bank[]); // Struct Account Display
void initialize(bank[]); // Struct Account Initialization
char transferprompt(bank s[]); // Transfer Menu
int createaccounts(); //Create Account Numbers and Balances
void time(); //Displays the Current date, month, year, and time.
void clearscreen(); //Prints 40lines to clear the screen
int main()
{
bank accounts[SIZE]; // Array of bank-account structs
initialize(accounts); // Removes garbage values
char select; //User input variable
bank *ptr;
ptr = &accounts[0];
menu(); //Runs MenuPrompt
cin >> select; //Grabs user input
select = static_cast<char>( tolower( select ) ); //Ensures user input is lowercase (for switch statement)
clearscreen();
switch ( select )
{
case 'a': //Creates Accounts
input(accounts);
clearscreen();
main();
display(accounts);
break;
case 'b': //Transfers between accounts
//display(accounts);
transferprompt(accounts);
//main();
break;
case 'c': //Displays day, month, year, time, + Account Information.
time();
break;
case 'd': //Exits Program
break;
default: //Invalid Input failsafe; Restarts menu prompt.
cout<<"Invalid selection. Restarting...\n";
main();
break;
}
}
char transferprompt(bank s[])
{
}
bank* input(bank s[]) // Creates Bank Accounts
{
bank accounts[SIZE]; // Array of bank-account structs
bank *ptr; // Pointer to struct
ptr = &accounts[0]; // Points pointer to array of bank-account structs
cout << "Account Creation Selected; Create " << SIZE << " accounts..." << endl;
for (int i = 0; i < SIZE ; i++)
{
cout << "Enter Account Number: ";
cin >> s[i].num;
s[i].checkdigit = s[i].num % 5;
cout << "Enter Account Balance: ";
cin >> s[i].bal;
}
return ptr;
}
void display(bank s[]) //Displays Bank Accounts
{
for (int i = 0; i < 4; i++)
{
cout << "Account: " << s[i].num << s[i].checkdigit;
cout << " has balance: $" << s[i].bal << endl;
}
}
void initialize(bank s[]) // Removes Garbage values
{
for (int i = 0; i < 4; i++)
{
s[i].num = 0;
s[i].checkdigit = 0;
s[i].bal = 0;
}
}
void clearscreen() // Clears screen
{
cout << string(40, '\n');
}
void time() // Display Time function
{
time_t t = time(NULL);
tm* ptr = localtime(&t); // ptr = Pointer to compute time
cout << endl;
cout << endl;
cout << "Date: " << (ptr->tm_mon)+1 <<"/"<< (ptr->tm_mday)<< "/" << (ptr->tm_year)+1900 << endl;
cout << "Time: " << (ptr->tm_hour) <<":"<< (ptr->tm_min)<< ":" << (ptr->tm_sec) << endl;
}
void menu() // Menu Prompt
{
cout << "Parkville Bank Client Program; Edit your accounts:\n";
cout << "a. Create " <<SIZE<<" accounts\n";
cout << "b. Transfer money from 1 account to another\n";
cout << "c. Display account balances\n";
cout << "d. Quit the program\n\n";
}
This function is not correct:
bank* input(bank s[]) // Creates Bank Accounts
{
bank accounts[SIZE]; // Array of bank-account structs
bank *ptr; // Pointer to struct
ptr = &accounts[0]; // Points pointer to array of bank-account structs
// ... lines removed ...
return ptr; // <-- Undefined behavior
}
You are returning a pointer to a local variable / array. Returning pointers or references to local variables is undefined behavior. The reason why is that since the array is local, once the function returns, it doesn't logically exist anymore. So you're eventually pointing to an non-existing entity.
What you probably wanted to do is something like this:
bank* input(bank* s) // Creates Bank Accounts
{
cout << "Account Creation Selected; Create " << SIZE << " accounts..." << endl;
for (int i = 0; i < SIZE ; i++)
{
cout << "Enter Account Number: ";
cin >> s[i].num;
s[i].checkdigit = s[i].num % 5;
cout << "Enter Account Balance: ";
cin >> s[i].bal;
}
return &s[0];
}
Since s was passed in, you probably meant to pass the address of the first element of this entity instead. Also note that this:
bank* input(bank s[]) // Creates Bank Accounts
is no different than this:
bank* input(bank* s) // Creates Bank Accounts
as arrays decay to pointers.
I would really recommend you use containers such as std::vector instead of raw arrays and global constants to keep track of the number of entities (for example, SIZE). Then
Another issue with your program is that you're recursively calling main. Don't do this, as it is not legal C++. Instead, use the proper looping constructs such as while() and do-while().
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I am currently making a small console based text game in C++ with visual studio 2010.
I have encounted the problem of; when I get my name entered and difficulty selected I go to make the introductory text and I enter :
cout <<"Welcome "<<userName<<"... You are a lone: "<<pickRace<<" Your journey will be a "<<difficulty<<" one.";
And I want it to show up as : Welcome Blake... you are a lone Human/Orc your journey will be a easy/medium/hard one.
But I comes up as Welcome Blake... you are a lone 1/2 your jouney will be a 1/2/3 one.
this is a problem I think due to my switch's could anyone tell me how I need to rewrite them to get it appear with the name instead of numbers?
original code :
cout <<"Please pick your race: \n";
cout <<"1 - Human\n";
cout <<"2 - Orc\n";
int pickRace;
cout <<"Pick your race: ";
cin >>pickRace;
switch (pickRace)
{
case 1:
cout <<"You picked the Human race.\n";
break;
case 2:
cout <<"You Picked the Orc race\n";
break;
default:
cout <<"Error - Invalid imput; only 1 or 2 allowed.\n";
}
int difficulty;
cout <<"\nPick your level diffuculty: \n";
cout <<"1 - Easy\n";
cout <<"1 - Medium\n";
cout <<"3 - Hard\n";
cout <<"Pick your level difficulty: ";
cin >>difficulty;
switch (difficulty)
{
case 1:
cout <<"You picked Easy.\n\n";
break;
case 2:
cout <<"You picked Medium.\n\n";
break;
case 3:
cout <<"You picked Hard.\n\n";
break;
default:
cout <<"Error - Invalid imut; only 1,2 or 3 allowed.\n";
}
You are storing pickRace and difficulty as integers. Try doing something like:
int pickRace;
string raceText; //we will store the race type using this
cout <<"Pick your race: ";
cin >>pickRace;
switch (pickRace)
{
case 1:
cout <<"You picked the Human race.\n";
raceText = "Human";
break;
case 2:
cout <<"You Picked the Orc race\n";
raceText = "Orc";
break;
default:
cout <<"Error - Invalid imput; only 1 or 2 allowed.\n";
}
Note the raceText string variable.
Repeat this for difficulty.
Then use raceText and difficultyText to print your message:
out <<"Welcome "<<userName<<"... You are a lone: "<<raceText<<" Your journey will be a "<<difficultyText<<" one.";
Consider using enums and overload operator<< and operator>> for them:
#include <iostream>
#include <cassert>
enum difficulty { EASY = 1, MEDIUM = 2, HARD = 3 };
std::istream& operator>>( std::istream& is, difficulty& d )
{
int i;
is >> i;
assert( i > 0 && i < 4 ); // TODO: Use real error handling, throw an exception
d = difficulty( i );
return is;
}
std::ostream& operator<<( std::ostream& os, difficulty d )
{
switch( d ) {
case EASY: return os << "easy";
case MEDIUM: return os << "medium";
case HARD: return os << "hard";
}
return os << "unknown[" << (int)d << "]";
}
int main()
{
difficulty d;
std::cout << "Pick difficulty: 1-easy, 2-medium, 3-hard: ";
std::cin >> d;
std::cout << "You picked difficulty: " << d << std::endl;
}
Why do you expect it to print string when you are storing choices as ints...
You can use std::map
#include <map>
std::map<int, std::string> difficulty;
difficulty[1] = "easy";
difficulty[2] = "medium";
difficulty[3] = "hard";
int choice_difficulty;
std::cin>>choice_difficulty;
/*Check if user entered correct number*/
std::map<int, std::string>::iterator it = difficulty.find(choice_difficulty);
if(it == difficulty.end())
std::cout << "wrong choice";
cout <<"Welcome "<<userName<<" Your journey will be a "<<difficulty[choice_difficulty];
You may want to use lookup tables to convert between enums or numeric IDentifiers (IDs) and the text they represent.
For example:
struct Race_Text_Entry
{
const char * text;
unsigned int id;
};
static const Race_Text_Entry race_name_table[] =
{
{"Unknown", 0},
{"Human", ID_HUMAN_RACE},
{"Orc", ID_ORC_RACE},
{"Elf", ID_ELF_RACE},
};
static const unsigned int NUM_RACE_ENTRIES =
sizeof(race_name_table) / sizeof(race_name_table[0]);
std::string Race_ID_To_Text(unsigned int id)
{
unsigned int i = 0;
std::string race_name = "Race unknown";
for (i = 0; i < NUM_RACE_ENTRIES; ++i)
{
if (race_name_table[i].id == id)
{
race_name = race_name_table.text;
break;
}
}
return race_name;
}
int main(void)
{
std::cout << "My race: " << Race_ID_To_Text(ID_RACE_HUMAN) << "\n";
return 0;
}
A nice advantage to the constant lookup table as an array, is that it can be stored in the read-only data section of the program and loaded with the constant data. The initialization time is negligible compared with creating a std::map variable during initialization.
pickRace and difficulty are Integers. You're printing integers instead of the actual difficulty. You need to somehow logically represent the difficulty (and pickRace)
I'm totally new and I don't know how else to ask this or what to even search for.
The case is this: I want to navigate through a menu with several sub-menus. In this example I'll just use "options" and a "game" to illustrate what I mean. Say you have a menu with 3 options.
1 - Start
2 - Options
3 - Quit
Choosing options should take you to another menu. Which would then look something like
1 - Difficulty
2 - Sound
3 - Back
Depending on where you go from here, there will be more sub menus obviously.
I've tried nesting do-while loops and all kinds of things but I just don't have enough understanding to know what it is I'm doing wrong.
Here is what I have so far:
#include <cstdlib>
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
int choice;
do{
cout << "Main Menu\n";
cout << "Please make your selection\n";
cout << "1 - Start game\n";
cout << "2 - Options\n";
cout << "3 - Quit\n";
cout << "Selection: ";
cin >> choice;
switch(choice) {
case 1:
cout << "Pew pew!\n";
break;
case 2:
cout <<"????\n";
break;
case 3:
cout << "Goodbye!";
break;
default:
cout << "Main Menu\n";
cout << "Please make your selection\n";
cout << "1 - Start game\n";
cout << "2 - Options\n";
cout << "3 - Quit\n";
cout << "Selection: ";
cin >> choice;
}
} while(choice !=3);
system("PAUSE");
return EXIT_SUCCESS;
}
Which works like a regular menu. But I have no idea where to go from here. I consulted some books, but finding anything even remotely related to this was completely random. Any help or examples would be greatly appreciated.
What happened with nesting tons of loops just made all loops execute simultaneously every time. How do I keep this from happening? Making more choices? (choice1-2-3 etc ? or what?)
Ok guys. Thanks for all the help. This is what I ended up with in the end.
It runs as I want it to and by max_'s example and Mike B's commentary I think this works pretty well.
Thanks alot everyone =)
#include <iostream>
#include <cstdlib>
using namespace std;
void menu();
void mainMenu();
void optionsMenu();
void options();
int choice1 = 0;
int choice2 = 3;
int main(int argc, char** argv) {
menu();
return 0;
}
void menu(){
do {
choice2 = 0;
mainMenu();
switch(choice1) {
case 1:
cout << "Pew pew!\n";
break;
case 2:
options();
break;
case 3:
break;
}
} while(choice1 != 3);
}
void options(void) {
do {
optionsMenu();
switch(choice2){
case 1:
cout << "So difficult!\n";
break;
case 2:
cout << "Beep!\n";
break;
case 3:
break;
default:
break;
}
} while(choice2 != 3);
}
void mainMenu(void) {
cout << "Main Menu\n";
cout << "1 - Start game\n";
cout << "2 - Options\n";
cout << "3 - Quit\n";
cout << "Please choose: ";
cin >> choice1;
}
void optionsMenu(void) {
cout << "Options Menu\n";
cout << "1 - Difficulty\n";
cout << "2 - Sound";
cout << "3 - Back\n";
cout << "Please choose: ";
cin >> choice2;
}
How about this (dunno if it compiles though):
#include <cstdlib>
#include <iostream>
using namespace std;
int GetInput()
{
int choice;
cin >> choice;
return choice;
}
void DisplayMainMenu()
{
cout << "Main Menu\n";
cout << "Please make your selection\n";
cout << "1 - Start game\n";
cout << "2 - Options\n";
cout << "3 - Quit\n";
cout << "Selection: ";
}
void DisplayOptionsMenu()
{
cout << "Options Menu\n";
cout << "Please make your selection\n";
cout << "1 - Difficulty\n";
cout << "2 - Sound\n";
cout << "3 - Back\n";
cout << "Selection: ";
}
void Options()
{
int choice = 0;
do
{
system("cls");
DisplayOptionsMenu();
choice = GetInput();
switch(choice)
{
case 1:
cout << "difficulty stuff";
break;
case 2:
cout << "sound stuff";
break;
case 3:
break;
default:
break;
}
} while(choice!=3);
}
int main(int argc, char *argv[])
{
int choice = 0;
do
{
system("cls");
DisplayMainMenu();
choice = GetInput();
switch(choice) {
case 1:
cout << "Pew pew!\n";
break;
case 2:
Options();
break;
case 3:
cout << "Goodbye!";
break;
default:
break;
}
} while(choice!=3);
system("PAUSE");
return EXIT_SUCCESS;
}
I'd recommend that you change a few things here. Are you familiar with object-oriented design? If not, it's highly recommended that you read about that if you're looking to write code in C++ (Or just writing code in general, as it's a pretty major aspect of many programming languages)
Consider treating each of your menus and submenus as individual objects. Each time you enter the loop, use an object pointer to call a method that prints the current menu text.
Then, take the input from the user as normal, and change the menu object you're using now.
This is perhaps not the most ideal way to do a console menu, but it will give you a very strong grounding in how objected-oriented programming works.
I've attached an example :
#include <iostream>
#include <string>
class BaseMenu
{
public:
BaseMenu() { m_MenuText = "This shouldn't ever be shown!"; } // This is the constructor - we use it to set class-specific information. Here, each menu object has its own menu text.
virtual ~BaseMenu() { } // This is the virtual destructor. It must be made virtual, else you get memory leaks - it's not a quick explaination, I recommend you read up on it
virtual BaseMenu *getNextMenu(int iChoice, bool& iIsQuitOptionSelected) = 0; // This is a 'pure virtual method', as shown by the "= 0". It means it doesn't do anything. It's used to set up the framework
virtual void printText() // This is made virtual, but doesn't *have* to be redefined. In the current code I have written, it is not redefined as we store the menu text as a string in the object
{
std::cout << m_MenuText << std::endl;
}
protected:
std::string m_MenuText; // This string will be shared by all children (i.e. derived) classes
};
class FirstMenu : public BaseMenu // We're saying that this FirstMenu class is a type of BaseMenu
{
FirstMenu()
{
m_MenuText = "Main Menu\n" // What we are doing here is setting up the string to be displayed later
+ "Please make your selection\n" // What we are doing here is setting up the string to be displayed later
+ "1 - Start game\n" // What we are doing here is setting up the string to be displayed later
+ "2 - Options\n" // What we are doing here is setting up the string to be displayed later
+ "3 - Quit\n" // What we are doing here is setting up the string to be displayed later
+ "Selection: "; // What we are doing here is setting up the string to be displayed later
}
BaseMenu *getNextMenu(int choice, bool& iIsQuitOptionSelected) // This is us actually defining the pure virtual method above
{
BaseMenu *aNewMenu = 0; // We're setting up the pointer here, but makin sure it's null (0)
switch (choice) // Notice - I have only done "options". You would obviously need to do this for all of your menus
{
case 2:
{
aNewMenu = new SecondMenu; // We're creating our new menu object here, and will send it back to the main function below
}
case 3:
{
// Ah, they selected quit! Update the bool we got as input
iIsQuitOptionSelected = true;
}
default:
{
// Do nothing - we won't change the menu
}
}
return aNewMenu; // Sending it back to the main function
}
};
class SecondMenu : public BaseMenu
{
SecondMenu()
{
m_MenuText = "OptionsMenu\n"
+ "Please make your selection\n"
+ "1 - ????"
+ "2 - dafuq?";
}
BaseMenu *getNextMenu(int choice, bool& iIsQuitOptionSelected) // This is us actually defining the pure virtual method above
{
BaseMenu *aNewMenu = 0; // We're setting up the pointer here, but makin sure it's null (0)
switch (choice) // Notice - I have only done options. You would obviously need to do this for all of your menus
{
case 1:
{
aNewMenu = new FirstMenu; // We're creating our new menu object here, and will send it back to the main function below
}
break;
case 2:
{
aNewMenu = new FirstMenu; // We're creating our new menu object here, and will send it back to the main function below
}
break;
default:
{
// Do nothing - we won't change the menu
}
}
return aNewMenu; // Sending it back to the main function
}
};
int main (int argc, char **argv)
{
BaseMenu* aCurrentMenu = new FirstMenu; // We have a pointer to our menu. We're using a pointer so we can change the menu seamlessly.
bool isQuitOptionSelected = false;
while (!isQuitOptionSelected) // We're saying that, as long as the quit option wasn't selected, we keep running
{
aCurrentMenu.printText(); // This will call the method of whichever MenuObject we're using, and print the text we want to display
int choice = 0; // Always initialise variables, unless you're 100% sure you don't want to.
cin >> choice;
BaseMenu* aNewMenuPointer = aBaseMenu.getNextMenu(choice, isQuitOptionSelected); // This will return a new object, of the type of the new menu we want. Also checks if quit was selected
if (aNewMenuPointer) // This is why we set the pointer to 0 when we were creating the new menu - if it's 0, we didn't create a new menu, so we will stick with the old one
{
delete aCurrentMenu; // We're doing this to clean up the old menu, and not leak memory.
aCurrentMenu = aNewMenuPointer; // We're updating the 'current menu' with the new menu we just created
}
}
return true;
}
Note that this might be a bit complex for starting out. I strongly recommend you read the other answers people have posted. It should give you a few approaches on how to do it, and you can progress from the basic up to the more complex, examining each change.
Looking at what you are trying to do, I would change how you are ensuring the user still want's to play the game first. Look at using a while loop to check if a variable is true or false (people tend to use boolean variables(bool's) for this, an int set to 1 or 0 will do the same). That removes the need for the do-while. Reading up on control logic (if/else, while, for loops) and logical operators (&& - and, || - or, != - not equal to) is recommended. Control logic makes your code do different things, booleans are quick for checking yes/no scenarios and logical operators allow you to check multiple items in one if statement.
Some reading: Loops
Edit: Have more links for reading material, don't have the rep to post them.
Secondly, use another variable (int or whatever suits you) to track what screen you are on.
Based on this selection, display different options but still take input 1,2,3 to decide upon the next action.
In some terrible pseudo-code here is what I would lean towards:
main()
{
int choice
int screen = 1
bool running = true
while(running) {
//Screen 1, Main menu
if(screen == 1) {
cout << stuff
cout << stuff
cout << option 1
cout << option 2
cout << option 3
cout << selection:
cin >> choice
}
else if(screen == 2){
//options screen here
}
else {
//default/error message
}
//add some choice logic here
if(screen == 1 && choice == 3){
//being on screen one AND choice three is quit
running = false;
}
else if(screen == 1 && choice == 2){
//etc..
}
}
}
This is my first proper answer, all terrible criticism is well recieved.