I've been building a menu driven console in C++, and I'm currently using switch-case as my options, but now I'm stuck in switch case.
Here's the scenario:
SCENARIO
Explanation:
After inputting invalid option in the main menu, it gives an error which prompts the user to re-input their desired option, now my problem is when the user inputs the correct option for the 2nd attempt, it loops back to the main menu instead of redirecting it to the next menu.
My Goal: To go to the 2nd menu directly from the default without redisplaying the main menu.
My Partial Code:
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
int choice;
int booknumber;
int booktitle;
int author;
int datepublished;
int e = 0;
void menu();
void inputbook();
void searchbook();
void borrowbook();
void exit();
//CLASS
class Books
{
public:
int booknumber;
string booktitle;
string author;
string datepublished;
Books(const int booknumber, const string booktitle, const string author, const string datepublished) : booknumber(booknumber), booktitle(booktitle), author(author), datepublished(datepublished) {}
};
//MAIN
int main()
{
while (true)
{
cout << endl;
if (e == 1)
{
break;
}
menu ();
}
return 0;
}
//MENU
void menu()
{
cout << "Welcome to DLC Library System\n";
cout << "Final Project in Advance Programming\n\n";
cout << "PROGRAMMER\n";
cout << "ME\n\n";
cout << "====================================\n";
cout << "[1] -------- Input Book ------------\n";
cout << "[2] -------- Search Book -----------\n";
cout << "[3] -------- Borrow Book -----------\n";
cout << "[4] -------- Exit Program ----------\n";
cout << "====================================\n";
cout << "Input your choice (Number Only): ";
cin >> choice;
switch (choice)
{
case 1:
inputbook ();
break;
case 2:
searchbook ();
break;
case 3:
borrowbook ();
break;
case 4:
exit();
break;
default:
while (choice < 1 || choice > 4)
{
cout << "Wrong Option\n";
cout << "Input your choice (Number Only): ";
cin >> choice;
if (choice < 1 || choice > 4)
{
continue;
}
}
}
}
// INPUT BOOK
void inputbook ()
{
int booknumber;
string booktitle;
string author;
string datepublished;
cout << "INPUT NEW BOOK\n\n";
cout << "Book Number: \n";
cin >> booknumber;
cout << "Book Title: \n";
cin >> booktitle;
cout << "Author: \n";
cin >> author;
cout << "Date Publish: \n";
cin >> datepublished;
Books(booknumber,booktitle, author, datepublished);
cout << "====================================\n";
cout << "[1] -------- Try Again? ------------\n";
cout << "[2] -------- Return to Menu --------\n";
cout << "[3] -------- Exit Program ----------\n";
cout << "====================================\n";
cout << "Input your choice (Number Only): ";
cin >> choice;
switch (choice)
{
case 1:
inputbook ();
break;
case 2:
menu ();
break;
case 3:
exit();
default:
cout << "Wrong Option";
}
}
It's a good idea to avoid repeating code. Here, you have a default case that is essentially an input loop, whereas you could have done that input loop at the start. So the way you wrote it, you still need a loop around the whole thing, plus more logic which makes the code harder to read and more bug-prone.
Why not simply:
cout << "====================================\n";
cout << "[1] -------- Input Book ------------\n";
cout << "[2] -------- Search Book -----------\n";
cout << "[3] -------- Borrow Book -----------\n";
cout << "[4] -------- Exit Program ----------\n";
cout << "====================================\n";
int choice;
bool validInput = false;
while (!validInput)
{
cout << "Input your choice (Number Only): ";
if (!(cin >> choice)) {
std::cerr << "Aborted\n";
return;
}
validInput = (choice >= 1 && choice <= 4);
if (!validInput) {
std::cout << "Invalid input\n";
}
}
switch(choice)
{
// ...
}
Now it's up to you to make your input routine more robust if you choose. Notice I've already bailed out of the function if the input fails. That could be from a stream error, but it could also be if the user enters a non-integer value.
You may instead wish to read your input as a string using std::getline and then convert that to an integer with std::stoi or parse the value from a std::istringstream.
Instead
continue;
try calling
inputbook();
so it won't go back.
That's a problem you are facing because you called switch-case again which is "continue". That's why it goes back to the menu when the user inputs the acceptable range of int you just set.
Just modify the code as below, and handle the valid input verification before entering the switch, in this way you can simply mitigate the issue you had!
cin >> choice;
while (choice < 1 || choice > 4)
{
cout << "Wrong Option\n";
cout << "Input your choice (Number Only): ";
cin >> choice;
if (choice < 1 || choice > 4)
{
continue;
}
}
switch (choice)
{
case 1:
inputbook ();
break;
case 2:
searchbook ();
break;
case 3:
borrowbook ();
break;
default:
exit();
break;
}
Related
I am doing a project for school and keep running into this reoccurring problem, my code does not seem to run as I have "undeclared identifiers." I have tried renaming them or redefining them but the same errors keep going or more. I am using VS code at the moment and read about maybe it was VScode itself but I get the same errors regardless.
#include <iostream>
#include <stdlib.h>
#include <string>
#include <fstream>
using namespace std;
class bankAccount {
public:
int accountNum;
string accountName;
string accountType;
double accountBalance;
double accountInterest;
double getInterest;
double updateBalance;
bankAccount(){
accountNum = 0;
accountName = "";
accountType = "";
accountBalance = 0.0;
accountInterest = 0.0;
}
void deposit()
{
long amount;
cout << "\n Please enter the amount you would like to deposit: ";
cin >> amount;
accountBalance = accountBalance + amount;
}
void withdraw()
{
long amount;
cout << "Please enter the amount you would like to withdraw: ";
cin >> amount;
if (amount <= accountBalance)
{
accountBalance = accountBalance - amount;
}
else
{
cout << "You do not have sufficient funds" << endl;
}
}
void interest(){
double getInterest;
cout << "Please enter desired interest amount: ";
cin >> getInterest;
}
void update(){
double updateBalance;
updateBalance = accountBalance * getInterest;
accountBalance += updateBalance;
}
void print(){
string print;
cout << "Welcome Back " << accountName << "," << endl;
cout << "\n Account Number: " << accountNum << endl;
cout << "\n Account Type: " << accountType << endl;
cout << "\n Current Balance: " << accountBalance << endl;
cout << "\n Account Interest: " << accountInterest << endl;
}
void openAccount(){
cout << "Enter Account Number: ";
cin >> accountNum;
cout << "Enter Account Holders Name: ";
cin >> accountName;
cout << "Enter Account Type: ";
cin >> accountType;
cout << "Enter Initial Balance: ";
cin >> accountBalance;
cout << "Enter Interest Rate: ";
cin >> accountInterest;
}
};
int main() {
int choice;
do
{
cout << "Please select the following options ";
cout << "\n 1:View Account";
cout << "\n 2: Open Account";
cout << "\n 3: Deposit" ;
cout << "\n 4: Withdraw ";
cout << "\n 5: Update account";
cin >> choice;
switch (choice)
{
case '1':
print ();
break;
case '2':
openAccount();
break;
case '3':
deposit();
break;
case '4':
withdraw();
break;
case '5':
updateBalance();
break;
}
} while (case !=5);
}
suggested creating an instance of class bankAccount somewhere before switch statement and call the functions like, instance_of_bankAccount.functionName();
At end of loop instead of (case !=5) it should be (choice != 5)
The problem with your code is that you do not have any instance of the class bankAccount, which means you try to call the function which actually does not exist. To fix it, you should create an object of the bankAccount type before the loop in which you can select the operation you want to perform:
int main() {
int choice;
bankAccount bankAcc; // this creates the object we need
do ...
And then for every case you wanted to call the function f(), add prefix bankAcc., so it becomes bankAcc.f(). In your code, it would be:
switch (choice) {
case '1':
bankAcc.print();
break;
case '2':
bankAcc.openAccount();
break;
case '3':
bankAcc.deposit();
break;
case '4':
bankAcc.withdraw();
break;
case '5':
bankAcc.updateBalance();
break;
}
Thanks to it, all functions called will know that they belong to bankAcc and they will change properties only of this particular object.
There is also another mistake in your code: did you really mean to use chars in your switch? At the moment cin >> choice reads an int, saves it in choice and then in switch it gets compared with all values corresponding to cases. The problem is that 1 is very different from '1' (which is casted to the value 49), so inputted int will never satisfy conditions from the menu you print.
Also, while (case !=5) should be changed to while (choice != 5).
I have a question,
Im new to c++ and general with coding.
I have this problem Im coding right now an Loader for a game and want to make a choice menu.
I have this error and I dont know how to fix it.
If you could help I would be happy.
This is my code https://ghostbin.co/paste/x8hz3
int DLL();
int Beta();
int select()
{
int selection;
do
{
selection = menu();
switch (selection)
{
case 1: DLL();
break;
case 2: Beta();
break; cout << "Exiting program.\n\n\n";
}
} while (selection != 2);
return 0;
}
int menu()
{
int choice;
cout << "Loader menu\n";
cout << "--------------------------------\n";
cout << "Normal\n";
cout << "--------------------------------\n";
cout << "1) Beta\n";
cout << "--------------------------------\n";
cout << "2) Dll methods\n";
cin >> choice;
while (choice < 1 || choice > 2) // Check to see if user's input is correct
{
cout << "Invalid Selection. Enter 1, or 2: ";
cin >> choice;
}
return choice;
}
int DLL()
{
cout << "Test" << endl;
}
int Beta()
{
cout << "Test" << endl;
}
You don't need to return anything for select() seemingly. You should declare the main() and write there:
.
select();
.
Important: You haven't defined any proper definition for menu(). On the beginning of the code, just add a single line int menu(); and you're good to go.
The things that i would like to accomplish is the functions of methods of the applications but getting many errors from the code which i don't completely understand and try to solve but came up with nothing.
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
class bank
{
char name [100],add[100],y;
int balance, amount;
public:
void open_account();
void deposite_money();
void withdraw_money();
void display_account();
};
void bank:open_account()
{
cout << "Enter your full name: ";
cin.ignore();
cin.getline(name,100);
cout << "What type of account you want to open savings (s) or current (c)";
cin >> y;
cout << "Enter amount of deposite: ";
cin >> balance;
cout << "Your account is created ";
}
void bank:deposite_money()
{
int a ;
cout << "Enter how much money you want to deposit: ";
cin >> a;
balance += a;
cout << "Your total deposit amount\n ";
}
void bank:display_account()
{
cout << "Enter the name: "<<name<<endl;
cout << "Enter your address: "<<add<<endl;
cout << "Type of account that you open: "<<y<<endl;
cout << "Amount you deposite: "<<balance<<endl;
}
void bank:withdraw_money()
{
cout << "Withdraw: ";
cout << "Enter the amount of withdrawing";
cin >> amount;
balance = balance - amount;
cout << "Now your total amount left is" <<balance;
}
int main()
{
int ch,x,n;
bank obj;
do
{
cout <<"01")open account\n";
cout <<"02")deposite money\n";
cout <<"03")withdraw money\n";
cout <<"04")display account\n";
cout <<"05")Exit\n";
cout << "Please select from the options above";
cin>>ch;
switch(ch)
{
case 1:"01")open account\n";
obj.open_account();
break;
case 2:"02")deposite money\n";
obj.deposite_money();
break;
case 3:"03")withdraw money\n";
obj.withdraw_money();
break;
case 4:"04")display account\n";
obj.display_account();
break;
case 5:
if(ch == 5)
{
cout << "Exit";
}
default:
cout<< "This is not the proper exit please try again";
}
cout << "\ndo you want to select the next step then please press : y\n";
cout << " If you want to exit then press : N";
x=getch();
if(x == 'y' || x == 'Y');
cout<< "Exit";
}
while (x == 'y' || x == 'Y');
getch();
return 0;
}
The errors that i am getting are
error stray '\'
error missing terminating character
error found ':' in nested name specifier
expected ; before ')' token
These are the errors that usually appears on the logs and has repeated a few times in different lines please help me so that i can finish this application i have learned a lot from making it and is looking forward to build more before my school starts Any help and suggestions on what i should do next is appreciated and advices on what i should do next will greatly be welcome for me to learn from this experience
Im using c++ btw and am trying to build some projects any advice for next time? How can improve myself after this errors and what should i next practice on like a next project that you guys would suggest me
See here:
#include <stdio.h>
#include <iostream>
using namespace std;
class bank
{
char name [100],add[100],y;
int balance, amount;
public:
void open_account();
void deposite_money();
void withdraw_money();
void display_account();
};
void bank::open_account()//: missing
{
cout << "Enter your full name: ";
cin.ignore();
cin.getline(name,100);
cout << "What type of account you want to open savings (s) or current (c)";
cin >> y;
cout << "Enter amount of deposite: ";
cin >> balance;
cout << "Your account is created ";
}
void bank::deposite_money()//: missing
{
int a ;
cout << "Enter how much money you want to deposit: ";
cin >> a;
balance += a;
cout << "Your total deposit amount\n ";
}
void bank::display_account()//: missing
{
cout << "Enter the name: "<<name<<endl;
cout << "Enter your address: "<<add<<endl;
cout << "Type of account that you open: "<<y<<endl;
cout << "Amount you deposite: "<<balance<<endl;
}
void bank::withdraw_money()//: missing
{
cout << "Withdraw: ";
cout << "Enter the amount of withdrawing";
cin >> amount;
balance = balance - amount;
cout << "Now your total amount left is" <<balance;
}
int main()
{
int ch,x,n;
bank obj;
do
{
cout <<"01)open account\n";//Delete " after Number
cout <<"02)deposite money\n";
cout <<"03)withdraw money\n";
cout <<"04)display account\n";
cout <<"05)Exit\n";
cout << "Please select from the options above";
cin>>ch;
switch(ch)
{
case 1:"01)open account\n";//Delete " after Number
obj.open_account();
break;
case 2:"02)deposite money\n";
obj.deposite_money();
break;
case 3:"03)withdraw money\n";
obj.withdraw_money();
break;
case 4:"04)display account\n";
obj.display_account();
break;
case 5:
if(ch == 5)
{
cout << "Exit";
}
default:
cout<< "This is not the proper exit please try again";
}
cout << "\ndo you want to select the next step then please press : y\n";
cout << " If you want to exit then press : N";
cin >> x;
if(x == 'y' || x == 'Y');
cout<< "Exit";
}
while (x == 'y' || x == 'Y');
}
Also don't use using namespace in headers, and in overall learn a better style. This is 80s C with C++ mixed in. Use containers not built in arrays, use iostream and overall get a good C++ book.
I am trying to code exception handling in my switch statement for a memnu in case user inputs something other than an int. Tried many different methods and still get continuous loop when user inputs a character.
I have tried using std exception but even with the include my compiler still sees error during build.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
class Exam
{
public:
int loadExam()
{
//ifstream infile;
//string examName = exam;
ifstream infile("exam.txt");
streambuf *cinbuf = cin.rdbuf(); //save old buf
cin.rdbuf(infile.rdbuf()); //redirect std::cin to infile.txt!
string line, theQuestion, questiontype, theAnswer;
int questionvalue;
//get the number of questions from the first line in the file
getline(cin,line);
numquestions = atoi(line.c_str());
for(int count = 0; count < numquestions; count++){
getline(cin,line);
//get the next line with the question type and the value of the question
int npos = line.size();
int prev_pos = 0;
int pos = 0;
while(line[pos]!=' ')
pos++;
questiontype = line.substr(prev_pos, pos-prev_pos);
prev_pos = ++pos;
questionvalue = atoi(line.substr(prev_pos, npos-prev_pos).c_str()); // Last word
//process a true/false question
if (questiontype == "TF")
{
myQuestions[count] = new QuestionTF;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
//process a multiple choice question
if (questiontype == "MC")
{
myQuestions[count] = new QuestionMC;
getline(cin,theQuestion);
myQuestions[count]->setQuestion(theQuestion,questionvalue);
}
}
cin.rdbuf(cinbuf); //restore cin to standard input
return numquestions;
}
void displayExamQuestions(int numquestions)
{
string qtype;
//print out the questions that have been processed
for(int count = 0; count<numquestions;count++)
{
qtype = myQuestions[count]->getQuestionType();
cout << qtype << " " << myQuestions[count]->getValue() << "\n";
myQuestions[count]->printOptions();
cout << "\n";
}
}
private:
Question *myQuestions[10];
int numquestions;
};
int main() {
Exam myExam;
int numquestions;
int choice;
while((choice = displayMenu())!=3)
switch(choice)
{
case 1:
numquestions = myExam.loadExam();
break;
case 2:
myExam.displayExamQuestions(numquestions);
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
getchar();
return 0;
}
int displayMenu()
{
int choice;
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam "<<endl;
cout << "\t2. Display Exam "<<endl;
cout << "\t3. Quit"<<endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
return choice;
}
Require output to read "Invalid selection, Please try again" when a user inputs a character or string of alpha characters.
In this case, validation should be handled by the displayMenu function for two reasons.
The displayMenu function says that it will return an integer so it should be responsible for ensuring the user inputs a number, not a char or string.
The displayMenu lists the options so it knows how many options are available, meaning it should also check that the integer is between 1 and 3.
Infinite loop with cin when typing string while a number is expected
int displayMenu() //This function should be responsible for validating that an
// int was inputed
{
int choice;
while (true)
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n'); //This clears out the stream if they entered a string
//Try using cin.ignore() and inputing a string to see what happens.
}
else if (choice >= 1 && choice <= 3)
{
break;
}
}
return choice;
}
You could decouple this second part by having a displayMenu function that simply prints the menu and a second function called getInput that doesn't care what integer is inputed. It would then be up to the calling function to make sure the value is between 1 and 3.
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <cctype>
using namespace std;
void displayMenu();
int getInput();
int main() {
int numquestions;
int choice = 0;
while (choice != 3)
{
displayMenu();
while ((choice = getInput()) < 1 || choice > 3)
{
std::cout << "Please pick a value between 1 and 3\n";
displayMenu();
}
switch (choice)
{
case 1:
cout << "Case 1\n";
break;
case 2:
cout << "Case 2\n";
break;
default:
cout << "Invalid choice. Try again.\n\n";
}
}
getchar();
return 0;
}
//Only responsible for getting an int
int getInput()
{
int choice;
while (true)
{
cin >> choice;
cout << "\n" << endl;
if (cin.fail())
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
std::cout << "Please enter a valid number\n";
}
else
{
break;
}
}
return choice;
}
//This function only displays a menu
void displayMenu()
{
cout << "\t===================== Exam Menu =====================" << endl;
cout << "\t1. Load Exam " << endl;
cout << "\t2. Display Exam " << endl;
cout << "\t3. Quit" << endl;
cout << "\t=====================================================" << "\n" << endl;
cout << "Please enter your selection: ";
}
If the user selects 1 or 2, function doesn't run. Any suggestions?
#include <iostream>
using namespace std;
void getTitle();
void getIsbn();
int main()
{
int choice = 0; // Stores user's menu choice
do
{
// Display menu
cout << " Main Menu\n\n\n";
// Display menu items
cout << " 1. Choose 1 to enter Title.\n";
cout << " 2. Choose 2 to enter ISBN.\n";
cout << " 3. Choose 3 to exit.\n";
// Display prompt and get user's choice
cout << " Enter your choice: ";
cin >> choice;
// Validate user's entry
while (choice < 1 || choice > 3)
{
cout << "\n Please enter a number in the range 1 - 3. ";
cin >> choice;
}
switch (choice)
{
case 1:
getTitle();
break;
case 2:
getIsbn();
break;
}
} while (choice != 3);
return 0;
}
void getTitle()
{
string title;
cout << "\nEnter a title: ";
getline(cin, title);
cout << "\nTitle is " << title << "\n\n\n";
}
void getIsbn()
{
string isbn;
cout << "\nEnter an ISBN: ";
getline(cin, isbn);
cout << "\nISBN is " << isbn << "\n\n\n";
}
The functions should certainly get called. What will happen, though, is that the newline generated when you press "Enter" to type the number will get returned by the getline(), and the function will return without really prompting you. You need to clear that newline. You can use ignore() to do this: add cin.ignore(); immediately after reading in choice to ignore the one character.