I have an assignment where I have to have a menu which is somewhat working, it can't crash or exit if I type in the wrong input and it can't have an endless loop. Although my menu doesn't exits or crashes it goes in to an endless loop where if I type in anything but an integer. Here is my code.
void mainMenu()
{
int option;
cout << "\t\t\t***** Project: Algorithms *****\n\n\n";
cout << "Enter your selection.\n\n";
cout << "1\tSearches.\n";
cout << "2\tCalculations and negations.\n";
cout << "3\tCopying.\n";
cout << "4\tExit the program.\n";
cout << "Please enter the menu next to each option.\n> " << flush;
cin >> option;
switch (option)
{
case 1: cout << "Yes!";
system("cls");
searchMenu();
break;
case 2: cout << "Yes!";
system("cls");
Calc_NegateMenu();
break;
case 3: cout << "Yes!";
system("cls");
copyMenu();
break;
case 4: cout << "Yes!";
exit(0);
break;
default: cout << "ERROR! Invalid input!";
system("cls");
mainMenu();
break;
}
}
The other menus.
void searchMenu()
{
int option;
cout << "\t\t\t***** Search *****\n\n\n";
cout << "Enter your selection.\n\n";
cout << "1\tSearch for a element with find.\n";
cout << "2\tSearch for an element with binary search.\n";
cout << "3\tSearch for pair elements.\n";
cout << "4\tBack to the main menu.\n";
cout << "Please enter the menu next to each option.\n> " << flush;
cin >> option;
switch (option)
{
case 1: cout << "Yes!";
system("cls");
searchMenu();
break;
case 2: cout << "Yes!";
system("cls");
Calc_NegateMenu();
break;
case 3: cout << "Yes!";
system("cls");
copyMenu();
break;
case 4: cout << "Yes!";
system("cls");
copyMenu();
break;
default: cout << "ERROR! Invalid input!";
system("cls");
mainMenu();
break;
}
}
void Calc_NegateMenu()
{
int option;
cout << "\t\t\t***** Calculate or Negate *****\n\n\n";
cout << "Enter your selection.\n\n";
cout << "1\tCalculate the total sum of all elements in the vector.\n";
cout << "2\tNegate all elements in the vector.\n";
cout << "3\tBack to the main menu.\n";
cout << "Please enter the menu next to each option.\n> " << flush;
cin >> option;
switch (option)
{
case 1: cout << "Yes!";
system("cls");
searchMenu();
break;
case 2: cout << "Yes!";
system("cls");
Calc_NegateMenu();
break;
case 3: cout << "Yes!";
system("cls");
mainMenu();
break;
default: cout << "ERROR! Invalid input!";
system("cls");
mainMenu();
break;
}
}
void copyMenu()
{
int option;
cout << "\t\t\t***** Copy *****\n\n\n";
cout << "Enter your selection.\n\n";
cout << "1\tCopy to list.\n";
cout << "2\tCopy to file.\n";
cout << "3\tBack to the main menu.\n";
cout << "Please enter the menu next to each option.\n> " << flush;
cin >> option;
switch (option)
{
case 1: cout << "Yes!";
system("cls");
searchMenu();
break;
case 2: cout << "Yes!";
system("cls");
Calc_NegateMenu();
break;
case 3: cout << "Yes!";
system("cls");
mainMenu();
break;
default: cout << "ERROR! Invalid input!";
system("cls");
mainMenu();
break;
}
}
When cin to an integer doesn't find one it sets an error flag and does not read from the input until the flag is cleared.
See this answer or this one.
Search on "cin infinite loop" and read the cin documentation.
Related
I am very new to programming so pardon my lack of knowledge. I am trying to create a simple menu in which I am going to execute a few problems by pressing 1,2,3 etc. but my code keeps looping over and over again and I can't understand why.
int main()
{
int choice;
do
{
cout << "\t|--------------------------- Menu ---------------------------|" << endl;
cout << "1.|- Добавяне на телефонни номера -|" << endl;
cout << "2.|- Извеждане на всички телефонни абонати на екрана -|" << endl;
cout << "3.|- Месечно потребление -|" << endl;
cout << "4.|- Изчисление на месечна такса -|" << endl;
cout << "5.|- Справки за абонатите с под меню -|" << endl;
cout << "6.|- Край на програмата -|" << endl;
switch(choice)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
cout << "|- Благодаря ви -|" << endl;
return 0;
}
}
while(choice != 6);
}
You need to use cin in your code in order to change what choice is every time that you go through the loop. Also it is a good idea to handle invalid user inputs. This is done by (!(cin >> choice)) until input will return true. While this is the case you want to cin.clear() and cin.ignore() to reset the state of the stream so that you can keep asking the user for a correct input.
#include<iostream>
using namespace std;
int main()
{
// it is a good idea to initialize the variable when you create it
int choice = 0;
do
{
cout << "\t|--------------------------- Menu ---------------------------|" << endl;
cout << "1.|- Добавяне на телефонни номера -|" << endl;
cout << "2.|- Извеждане на всички телефонни абонати на екрана -|" << endl;
cout << "3.|- Месечно потребление -|" << endl;
cout << "4.|- Изчисление на месечна такса -|" << endl;
cout << "5.|- Справки за абонатите с под меню -|" << endl;
cout << "6.|- Край на програмата -|" << endl;
// this loop will handle incorrect inputs from the user
// for example entering a char, when the stream is expecting an int
while (!(cin >> choice))
{
cin.clear();
cin.ignore();
cout << "Please enter a valid choice: ";
cin >> choice;
}
switch (choice)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
cout << "|- Благодаря ви -|" << endl;
return 0;
}
} while (choice != 6);
}
So I got an assignment to make a program that allows the user to select three favourite destinations in order. It repeats until the user decides to stop. Once the user decides to discontinue, the program then displays the total votes received for each destination according to preference by the users. One user will have three preferences and if the program repeats four times, it means four users’ preferences are recorded. Therefore a total of 12 preferences are recorded in this instance.
I have tried to limit input for the loop to work but it seems it will only work with a decision which is not necessary at the beginning of the program, which i want to remove altogether.
Also, I have tried to limit output for each of the decisions but it will only run once and then move on to the next choice. Is there any way to get a persistent entry prompt that will only continue after a valid input.
Lastly, is there any way I could improve the code by using switch/break statements instead of if/else?
Here's my code:
cout << "Do you want to go forth with this program?\nType y to confirm. The
program will exit if anything else is entered: ";
cin >> Decision;
while (Decision=="y")
{
cout << "\n\nNow please enter the code for which your destination corresponds to: " << endl; //first decision
cin >> Choice1;
if (Choice1 == 1)
{
LasVegas1++;
}
else if (Choice1 == 2)
{
Tokyo1++;
}
if (cin.fail())
{
cout << "Please enter a valid choice" << endl;
continue;
}
cout << " \nNow please enter the second code: " << endl; //second decision
cin >> Choice2;
if (Choice2 == 1)
{
LasVegas2++;
}
else if (Choice2 == 2)
{
Tokyo2++;
}
else
{
cout << "\nError! Please enter a valid code as shown above!\n";
cout << "\nNow please enter the second code: ";
cin >> Choice2;
}
cout << " \nNow please enter the third code: " << endl; //third decsion
cin >> Choice3;
if (Choice3 == 1)
{
LasVegas3++;
}
else
{
cout << "\nError! Please enter a valid code as shown above!\n";
cout << "\nNow please enter the third code: ";
cin >> Choice3;
}
cout << " \nDo you wish to select three more destinations? (Y/N): " << endl;
cin >> Decision;
}
What I would do is to put all your city variables into an array and then convert your three sets of code into a for loop. Something like:
for(int i = 0; i < 3; i++) {
if(Choice1 == 0) {
rome[i]++;
}
//etc
So that way you wouldn't need to repeat the same code three times. Also you only need one Choice variable. (You can just reset it at each iteration of the loop)
Additionally you could implement a switch statement to clean up the code a little:
switch(Choice1) {
case 1:
LasVegas1++;
break;
case 2:
Tokyo1++;
break;
case 3:
London1++;
break;
case 4:
Paris1++;
break;
case 5:
Dubai1++;
break;
case 6:
Mumbai1++;
break;
case 7:
NewYork1++;
break;
case 8:
Sydney1++;
break;
case 9:
Auckland1++;
break;
case 10:
Rome1++;
break;
case 11:
Other1++;
break;
}
It can be heavily simplified by the use of "Switch" and "Break".
Like the code that i have written. Have a look :
char input;
int choice;
void Permission() {
cout << "Do you want to go forth with this program ? (y to confirm)" << flush;
cin >> input;
cout << endl;
}
void Decision1() {
if(input == 'y') {
cout << "Now please enter the code for which your destination corresponds to : " << flush;
cin >> choice;
switch (choice) {
case 1:
cout << "LasVegas " << endl;
break;
case 2:
cout << "Tokyo " << endl;
break;
case 3:
cout << "London " << endl;
break;
case 4:
cout << "Paris " << endl;
break;
case 5:
cout << "Dubai " << endl;
break;
case 6:
cout << "Mumbai " << endl;
break;
case 7:
cout << "New York " << endl;
break;
case 8:
cout << "Sydney " << endl;
break;
case 9:
cout << "Auckland " << endl;
break;
case 10:
cout << "Rome " << endl;
break;
case 11:
cout << "Other " << endl;
break;
default:
cout << "Invalid option. Enter Again : " << flush;
cin >> choice;
}
cout << endl;
}
}
void Decision2() {
cout << "Now please enter the second code: " << flush;
cin >> choice;
switch (choice) {
case 1:
cout << "LasVegas " << endl;
break;
case 2:
cout << "Tokyo " << endl;
break;
case 3:
cout << "London " << endl;
break;
case 4:
cout << "Paris " << endl;
break;
case 5:
cout << "Dubai " << endl;
break;
case 6:
cout << "Mumbai " << endl;
break;
case 7:
cout << "New York " << endl;
break;
case 8:
cout << "Sydney " << endl;
break;
case 9:
cout << "Auckland " << endl;
break;
case 10:
cout << "Rome " << endl;
break;
case 11:
cout << "Other " << endl;
default:
cout << "Invalid option. Enter Again : " << flush;
cin >> choice;
}
cout << endl;
}
void Decision3() {
cout << "Now please enter the third code: " << flush;
cin >> choice;
switch (choice) {
case 1:
cout << "LasVegas " << endl;
break;
case 2:
cout << "Tokyo " << endl;
break;
case 3:
cout << "London " << endl;
break;
case 4:
cout << "Paris " << endl;
break;
case 5:
cout << "Dubai " << endl;
break;
case 6:
cout << "Mumbai " << endl;
break;
case 7:
cout << "New York " << endl;
case 8:
cout << "Sydney " << endl;
break;
case 9:
cout << "Auckland " << endl;
break;
case 10:
cout << "Rome " << endl;
break;
case 11:
cout << "Other " << endl;
break;
default:
cout << "Invalid option. Enter Again : " << flush;
cin >> choice;
}
cout << endl;
}
int main() {
Permission();
Decision1();
Decision2();
Decision3();
system("PAUSE");
return 0;
}
I don't know that how to get the loop at the default when the user enters the wrong option. I was able to give the "cin" once. Update this problem if you know how to.
Yes you could improve with a switch statement. Theres also something called a do while loop you should look into.
I want to display an interface asking the user whether or not they want to use checkings or savings account, and then when they choose bring them to my generic display menu. But I'm not quite sure how to set it up. I was told to make Account objects and use a pointer, but as you can see I'm stuck. If anyone could give me any insight on how I would do this, I would greatly appreciate it.
Here is my code:
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
private:
double balance; // Account balance
double interestRate; // Interest rate for the period
double interest; // Interest earned for the period
int transactions; // Number of transactions
public:
Account(double iRate = 0.045, double bal = 0)
{ balance = bal;
interestRate = iRate;
interest = 0;
transactions = 0; }
void setInterestRate(double iRate)
{ interestRate = iRate; }
void makeDeposit(double amount)
{ balance += amount; transactions++; }
bool withdraw(double amount); // Defined in Account.cpp
void calcInterest()
{ interest = balance * interestRate; balance += interest; }
double getInterestRate() const
{ return interestRate; }
double getBalance() const
{ return balance; }
double getInterest() const
{ return interest; }
int getTransactions() const
{ return transactions; }
};
#endif
int main()
{
Account Savings;
Account Checkings;
Account *ptr;
Account savings; // Savings account object
char choice; // Menu selection
// Set numeric output formatting.
cout << fixed << showpoint << setprecision(2);
do
{
// Display the menu and get a valid selection.
displayMenu();
cin >> choice;
while (toupper(choice) < 'A' || toupper(choice) > 'G')
{
cout << "Please make a choice in the range " << "of A through G:";
cin >> choice;
}
// Process the user's menu selection.
switch(choice)
{
case 'a':
case 'A': cout << "The current balance is $";
cout << savings.getBalance() << endl;
break;
case 'b':
case 'B': cout << "There have been ";
cout << savings.getTransactions() << " transactions.\n";
break;
case 'c':
case 'C': cout << "Interest earned for this period: $";
cout << savings.getInterest() << endl;
break;
case 'd':
case 'D': makeDeposit(savings);
break;
case 'e':
case 'E': withdraw(savings);
break;
case 'f':
case 'F': savings.calcInterest();
cout << "Interest added.\n";
}
} while (toupper(choice) != 'G');
return 0;
}
void displayMenu()
{
cout << "\n Welcome to The Bank \n";
cout << "-----------------------------------------\n";
cout << "A) Display the account balance\n";
cout << "B) Display the number of transactions\n";
cout << "C) Display interest earned for this period\n";
cout << "D) Make a deposit\n";
cout << "E) Make a withdrawal\n";
cout << "F) Add interest for this period\n";
cout << "G) Exit the program\n\n";
cout << "Enter your choice: ";
}
void makeDeposit(Account *acct)
{
double dollars;
cout << "Enter the amount of the deposit: ";
cin >> dollars;
cin.ignore();
acct.makeDeposit(dollars);
}
void withdraw(Account *acct)
{
double dollars;
cout << "Enter the amount of the withdrawal: ";
cin >> dollars;
cin.ignore();
if (!acct.withdraw(dollars))
cout << "ERROR: Withdrawal amount too large.\n\n";
}
Try something like this:
char displayAccountSelectionMenu();
char displayAccountActionMenu();
void makeDeposit(Account *acct);
void withdraw(Account *acct);
int main()
{
Account Savings;
Account Checkings;
Account *acct = NULL;
char choice; // Menu selection
do
{
// Display the menu and get a valid selection.
choice = displayAccountSelectionMenu();
// Process the user's menu selection.
switch (choice)
{
case 'A':
acct = &Savings;
break;
case 'B':
acct = &Checkings;
break;
case 'C':
return 0;
}
// Set numeric output formatting.
cout << fixed << showpoint << setprecision(2);
do
{
// Display the menu and get a valid selection.
choice = displayAccountActionMenu();
// Process the user's menu selection.
switch (choice)
{
case 'A':
cout << "The current balance is $"
<< acct->getBalance() << endl;
break;
case 'B':
cout << "There have been "
<< acct->getTransactions()
<< " transactions." << endl;
break;
case 'C':
cout << "Interest earned for this period: $"
<< acct->getInterest() << endl;
break;
case 'D':
makeDeposit(acct);
break;
case 'E':
withdraw(acct);
break;
case 'F':
acct->calcInterest();
cout << "Interest added." << endl;
break;
case 'G':
break;
case 'H':
return 0;
}
}
while (choice != 'G');
}
while (true);
return 0;
}
char displayAccountSelectionMenu()
{
char choice;
cout << "\n Welcome to The Bank \n";
cout << "-----------------------------------------\n";
cout << "Select an account:\n";
cout << "A) Savings\n";
cout << "B) Checking\n";
cout << "C) Exit the program\n\n";
cout << "Enter your choice: ";
cin >> choice;
choice = toupper(choice);
while ((choice < 'A') || (choice > 'C'))
{
cout << "Please make a choice in the range of A through C:";
cin >> choice;
choice = toupper(choice);
}
return choice;
}
char displayAccountActionMenu()
{
char choice;
cout << "\n Welcome to The Bank \n";
cout << "-----------------------------------------\n";
cout << "Select an action:\n";
cout << "A) Display the account balance\n";
cout << "B) Display the number of transactions\n";
cout << "C) Display interest earned for this period\n";
cout << "D) Make a deposit\n";
cout << "E) Make a withdrawal\n";
cout << "F) Add interest for this period\n";
cout << "G) Select a different account\n";
cout << "H) Exit the program\n\n";
cout << "Enter your choice: ";
cin >> choice;
choice = toupper(choice);
while ((choice < 'A') || (choice > 'H'))
{
cout << "Please make a choice in the range of A through H:";
cin >> choice;
choice = toupper(choice);
}
return choice;
}
void makeDeposit(Account *acct)
{
//...
}
void withdraw(Account *acct)
{
// ...
}
This is a block of code from a book I've been studying and trying to improve upon, but I'm having trouble finding a way to give the player another chance at selecting the difficulty after entering the default choice. This is a very simple console text-based game and when the player chooses an incorrect choice, the game doesn't allow the player to re-choose.
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Difficulty Levels\n\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n\n";
int choice;
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "You picked Easy\n";
break;
case 2:
cout << "You picked Normal\n";
break;
case 3:
cout << "You picked Hard\n";
break;
default:
cout << "Your choice is invalid.\n";
}
system("pause");
return 0;
}
You can refactor the switch into a function, which can be called whenever the player wants to change their difficulty choice.
int choose()
{
int choice;
cout << "Difficulty Levels\n\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n\n";
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "You picked Easy\n";
break;
case 2:
cout << "You picked Normal\n";
break;
case 3:
cout << "You picked Hard\n";
break;
default:
cout << "Your choice is invalid.\n";
choice = 0; //this will signal error
}
return choice;
}
int _tmain(int argc, _TCHAR* argv[])
{
int choice = 0;
while(choice == 0){choice = choose();};
system("pause");
return 0;
}
Now whenever the player decides to change difficulty (maybe they enter a special letter) you can use choice = choose() to alter the difficulty.
Wrap the input code in a do-while.
bool valid = true;
do
{
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "You picked Easy\n";
break;
case 2:
cout << "You picked Normal\n";
break;
case 3:
cout << "You picked Hard\n";
break;
default:
cout << "Your choice is invalid.\n";
valid = false;
}
} while(!valid);
Assignment"Rewrite the menu chooser program from chapter using an enumerator to represent difficulty levels. the variable choice will still be of type int."
The first set of code is the original menu chooser program in its original untainted form. The second set of code is what I added to it in order to complete the assignment.
The only thing I want to ask is: Did I complete my assignment correctly. If I did it wrong, can someone please explain what I did wrong. I'm very new at this.
Code Set # 1 - Original
#include <iostream>
using namespace std;
int main()
cout << "Difficulty Levels\n\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n";
int choice;
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 1:
cout << "You picked Easy.\n";
break;
case 2:
cout << "You picked Normal.\n";
break;
case 3:
cout << "You picked Hard.\n";
break;
default:
cout << "You made an illegal choice.\n";
}
return 0;
}
Code Set # 2 - Assignment
#include <iostream>
using namespace std;
int main()
{
cout << "Difficulty Levels\n\n";
cout << "0 - Novice\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n";
cout << "4 - Unbeatable\n\n";
enum {Novice = 0, Easy = 1, Normal = 2, Hard = 3, Unbeatable = 4};
int choice;
cout << "Choice: ";
cin >> choice;
switch (choice)
{
case 0:
cout << "You have picked Novice.\n";
break;
case 1:
cout << "You picked Easy.\n";
break;
case 2:
cout << "You picked Normal.\n";
break;
case 3:
cout << "You picked Hard.\n";
break;
case 4:
cout << "You picked Unbeatable.\n";
break;
default:
cout << "You made an illegal choice.\n";
}
return 0;
}
I would do something like this:
#include <iostream>
using namespace std;
int main()
{
cout << "Difficulty Levels\n\n";
cout << "0 - Novice\n";
cout << "1 - Easy\n";
cout << "2 - Normal\n";
cout << "3 - Hard\n";
cout << "4 - Unbeatable\n\n";
enum {NOVICE = 0, EASY = 1, NORMAL = 2, HARD = 3, UNBEATABLE = 4};
int choice;
cout << "Choice: ";
cin >> choice;
switch (choice) {
case NOVICE:
cout << "You have picked Novice.\n";
break;
case EASY:
cout << "You picked Easy.\n";
break;
case NORMAL:
cout << "You picked Normal.\n";
break;
case HARD:
cout << "You picked Hard.\n";
break;
case UNBEATABLE:
cout << "You picked Unbeatable.\n";
break;
default:
cout << "You made an illegal choice.\n";
break;
}
return 0;
}
This way you're showing you're at least using your enum.