I am trying to make my first text-to-play game in C++. The only problem is that the default statement in my code is making the game glitch. I am trying to use another function called exceptionHandler to deal with the default statement, but it doesn't seem to be working. Any suggestions? Here is the code:
#include <iostream>
#include <cstdlib>
using namespace std;
void space(), menu(), exceptionHandler();
int back1, back2;
int main()
{
cout << "Siddiqui Interactive presents..." << endl;
cin.get();
system("CLS");
cout << "Outland" <<endl;
cin.get();
int bob = 0;
//to loop back to main menu
while(bob < 5){
system("CLS");
cout << "Outland" <<endl;
space();
cout << "Press 1 to begin" <<endl;
cout << "Press 2 for credits" <<endl;
cout << "Press 3 to quit" <<endl;
int switch1;
cin >> switch1;
switch(switch1){
case 1:
//nothing here for now
break;
case 2:
system("CLS");
menu();
if(back1 == 1){
system("CLS");
//clears screen to loop back to the menu
}
break;
case 3:
return 0;
break;
default:
system("CLS");
exceptionHandler();
}
}
return 0;
}
void menu(){
//to create a function for the menu, saves time
cout << "This game was coded by: Shahmir Siddiqui and Ibrahim" <<endl;
cout << "Outland was designed by: Azmir Siddiqui" <<endl;
space();
cout << "Press 1 to go back" <<endl;
cin >> back1;
}
void space(){
//just saves time
cout << "" <<endl;
}
void exceptionHandler(){
//to handle exceptions or errors
system("CLS");
cout << "Invalid!" <<endl;
space();
cout << "Press 1 to go back" <<endl;
cin >> back2;
if(back2 == 1){
system("CLS");
//also clears screen to loop back to main menu
}
}
EDIT: Let's say, I typed in d instead of 1, it just keeps on fluctuating rapidly between error screen and main menu.
cin >> switch1 tries to read in an integer. If you type d (which can't be converted to an int, it doesn't "eat" the bad input so you must clear it manually.
Try adding this to your error case:
cin.clear();
cin.ignore(INT_MAX, '\n');
Related
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;
}
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.
So I have a Menu that I used to run my text based game. The problem is that I can't seem to exit my game.Every time I run it, I can do option 1 and go to my game, and options 2 and 3 work just fine. But For option 4, I am unable to exit my game. All it does is print out what I ask it to print out, before giving the menu options again (as if it was just looping).
I have googled a lot, and tried to figure out why but I am not sure.
If someone can advise me what to do or tell me where my mistake is, it would be greatly appreciated. Please let me know if you want to see more code. All I have displayed here is the Menu Function.
void menu() {
char choice = -1;
while(choice != '1')
{
cout << "\n* * * * *" << endl;
cout << " The Dark Maze\n";
cout << "\n* * * * *" << endl;
cout << "\n=====================";
cout << "\n Main Menu |";
cout << "\n=====================";
cout << "\n 1 - Start Game |";
cout << "\n 2 - Instructions |";
cout << "\n 3 - Storyline |";
cout << "\n 4 - Exit |";
cout << "\n=====================";
cout << "\n";
cout << "\n Enter choice: ";
cout << "\n";
cin >> choice;
switch (choice)
{
case '1':
cout << "\n" << endl;
cout << "\n But we can't start the game just yet..." << endl;
break; //heads to game
case '2':
Instructions();
break;
case '3':
Storyline();
break;
case '4':
cout << "\n Well, if you really don't want to play... you don't have to." << endl;
break; //just say exit?? break isnt making it stop
default:
cout << "Invalid Character entered\n";
cout << "\n";
cout << "Press Space to continue\n";
}// end of switches
cin.get();
} // end of while
}// end of menu
You shouldn't be using while loop for this. Try do-while loop for this kind of menus like this:
do
{
// your menu here...
cin >> choice;
switch ( choice )
{
case ...
...
}
// cin.get();
// ^^^^^^^^^^ You don't need this...
} while ( choice != '4' );
Some points to help you:
Use an enum to define your menu choices. (OR an enum class).
You can simply write a printMenu() function to print the menu in the main loop. Another function to process the choice.
For example:
void startGame()
{
char choice = INVALID_OPTION; // INVALID_OPTION => default invalid value
do
{
printMenu();
cin >> choice;
processChoice( choice );
} while ( choice != EXIT ); // EXIT => #define or an enum
}
You can use exit() to terminate your program with a given return value:
case '4':
std::cout << "blahblahblah";
std::exit(0);
break; // No longer necessary
It's prerequisite and prototype is
#include <cstdlib>
namespace std{
void exit(int status);
}
just use return instead break blow case '4' . not perfect but can work.
i try to do a simple menu using switch. I also want to do a check if the user made a valid input (Only int from 1 to 4). Entering -4 or 44 is working fine with this check. But if i enter something like "w" it gives me a infinite loop.
I'm guessing i need another if / else with if (!cin) blabla else go ahead with switch.
But i'm not sure how i do that the else is starting the switch.
int menu() {
int enter;
bool exit = false;
do {
cout << "Wie soll angefangen werden: " << endl; //Enter your choice
cout << "1 - Spiel starten" << endl; // do game();
cout << "2 - Highscore " << endl; //do score();
cout << "3 - Quiz starten " << endl; //do quiz();
cout << "4 - Ende " << endl; //end the programm
cin >> enter;
switch (enter) {
case 1:
game();
break;
case 2:
score();
break;
case 3:
showQuizDialog();
break;
case 4:
exit = true;
break;
default:
cout << "Keine gültige Eingabe, nochmal: " << endl; //invalid input, again
void flushCin();
} //end of switch
} while (exit == false);
}//end of menu();
It's because the input is trying to get an integer. When the input is not an integer, the input is left in the buffer, so next time around in the loop the same input is still there.
Also, you are not calling the flushCin function in the default case, you are declaring it. You might want to remove the void keyword. I guess it does the correct thing? (I.e. calling std::cin.ignore() and std::cin::clear().)
Read into a string and try to convert to int:
#include <sstream>
#include <string>
using namespace std;
int menu() {
int enter;
string str;
bool exit = false;
do {
cout << "Wie soll angefangen werden: " << endl; //Enter your choice
cout << "1 - Spiel starten" << endl; // do game();
cout << "2 - Highscore " << endl; //do score();
cout << "3 - Quiz starten " << endl; //do quiz();
cout << "4 - Ende " << endl; //end the programm
cin >> str;
istringstream buffer(str);
buffer >> enter;
switch (enter) {
case 1:
game();
break;
case 2:
score();
break;
case 3:
showQuizDialog();
break;
case 4:
exit = true;
break;
default:
cout << "Keine gültige Eingabe, nochmal: " << endl; //invalid input, again
void flushCin();
} //end of switch
} while (exit == false);
return enter;
}//end of menu();
If entering other things than numbers into an int value directly this might not fit into the reserved space of an int and can result in funny behaviour. So just read into a string first and then interpret it.
I am not sure if being in linux makes any different, but i have found online that this:
cout << "Press Enter to Continue...";
cin.ignore(numeric_limits<streamsize>::max(),'\n');
Should be sufficient, with #include<limits> in the header of course.
However, it does not seem to work in my program.
It compiles, it runs, but it does not wait.
Basically, i have a menu, which lead to a method call to display a list of people on the screen. I wish to pause that list before the system goes back to the menu.
Here is my code from the menu:
//Manager's Menu
void SelectionPage::showManagerMenu(){
char option;
while(true)
{
system("clear"); //Clears the terminal
cout<<" Flat Manager's Menu"<<endl<<endl; //Display manager's menu
cout << "Select Manager option" << endl;
cout << "a) Add a new Flat Member" << endl;
cout << "b) Delete an existing Flat Member" << endl;
cout << "c) List Flat Members" << endl;
cout << "d) Duties" <<endl;
cout << "e) Resources" <<endl;
cout << "f) Reset System" <<endl;
cout << "q) Exit" << endl;
cout << "make selection: ";
cin >> option;
switch(option) { //Takes the user to the corresponding menu or method
case 'a': system("clear");
memberList.addNewFlatMember(points);
break;
case 'b': system("clear");
memberList.deleteFlatMember();
break;
case 'c': system("clear");
memberList.listFlatMembers();
break;
case 'd': system("clear");
showDutiesMenu();
break;
case 'e': system("clear");
showResourcesMenu();
break;
case 'f': //reset();
break;
case 'q': exit(0);
default: cout << "Option not recognised: " << option << endl;
showManagerMenu();
}
}
}
the option i wish to select is c) which leads to:
//Show the current flat population
void MemberManagement::listFlatMembers(){
cout<<" Member List"<<endl<<endl;
importFlatMembers(); //get flat member info from file
for( int count = 0; count<flatMemberList.size(); count++){
cout << count+1<<". "<<flatMemberList[count].getName() << endl;
}
cout << "Press any key to Continue...";
cin.ignore(numeric_limits<streamsize>::max(),'\n');
return;
}
if you want to see any other bit of my code, feel free to let me know.
Thanks in advance.
Couldn't you just use cin.get() (get one character)?
In *nix, terminals usually wait for a whole line of input before sending anything to the program. Which is why the example code you posted said "Press Enter to Continue...";, and then discarded everything until the next newline.
To avoid that, you should put your terminal in non-canonical mode, which can be done using the POSIX termios(3) functions, as explained in How to check if a key was pressed in Linux?.
Here is a snippet from my code. It works in both windows and linux.
#include <iostream>
using std::cout;
using std::cin;
// Clear and pause methods
#ifdef _WIN32
// For windows
void clearConsole() {
system("cls");
}
void waitForAnyKey() {
system("pause");
}
#elif __linux__
// For linux
void clearConsole() {
system("clear");
}
void waitForAnyKey() {
cout << "Press any key to continue...";
system("read -s -N 1"); // Continues when pressed a key like windows
}
#endif
int main() {
cout << "Hello World!\n";
waitForAnyKey();
clearConsole();
return 0;
}