So i make a turn based dos game, And i have a switch() function which gives me a bug.. :
int hp;
int mana;
do
{
cout<<"Enter your arg here";
cin>>choice;
cout<<"Hahaha that won't stop me";
switch(choice)
{
case 1:
mana--;
mana--;
hp--;
hp--;
cout<<"Woosh";
}
}
while(1)
{
cout<<endl;
}
Ok so let me explain the bug :
When the player inputs choice variable it will just skip the switch() function an just go continue with cout<<"Hahaha that won't stop me";. How do i fix that?
PS : Sorry for my bad english, and if there is a misswriting on this post. I'm so sorry about that.
First of all, switch is not a function, it's a statement. That means, it doesn't behave like functions. What you've written here doesn't match with what you want.
What the program does is:
printing the first line
reading the input
printing the second line
switching on the input
What you want is:
printing the first line
reading the input
switching on the input
printing the second line on default case
So let's reorder your code.
cout << "Enter your arg here";
cin >> choice;
switch (choice)
{
case 1:
mana -= 2;
hp -= 2;
cout << "Woosh";
break;
default:
cout << "Hahaha that won't stop me";
break;
}
And don't forget to write break; on every case, including default one.
Related
This question already has answers here:
Why cin inside while doesn't stop to get user input?
(2 answers)
Closed 4 years ago.
When I give a character input to 'choice', default statement is executed repeatedly. 'cin' instruction is not blocking the execution.
#include<iostream>
using namespace std;
main()
{
int choice;
do{
cout<<"Enter your choice: ";
cin>>choice; //I'm giving character i/p even though 'choice' is int
switch(choice)
{
case 1:cout<<"\n 1 \n";
break;
case 2:cout<<"\n 2 \n";
break;
case 3:cout<<"\n 3 \n";
break;
case 4:cout<<"\n 4 \n";
return 0;
default:cout<<"An Invalid choice."<<endl;
}
}while(1);
cout<<"\n Hello";
}
The cout statement shouldnt be blocking, that would be the cin you are referring to.
In this case, cin reading in the value, but NOT the newline after it, so the next time you read a value, you are reading the newline.
So you need to read in the new line values before reading the next value.
Try the following code by giving end limit to choice variable.
main(){
int choice;
do{
cout<<"Enter your choice: ";
cin>>choice; //I'm giving character i/p even though 'choice' is int
switch(choice)
{
case 1:cout<<"\n 1 --\n";
break;
case 2:cout<<"\n 2 \n";
break;
case 3:cout<<"\n 3 \n";
break;
case 4:cout<<"\n 4 \n";
return 0;
default:cout<<"An Invalid choice."<<endl;
}
}while(choice>4);
cout<<"\n Hello";
}
The break always breaks the innermost loop.
A break statement terminates execution of the smallest enclosing switch or iteration statement.
If you want to break out of both loops, use a label and jump with goto.
So basically its going into infinite loop since your break is only getting out from switch case.
I am currently getting to grips with how to correctly implement multiple functions in my programs and I think I have got the right idea but I am just wanting to clarify.
When putting some logic into a particular function, should I be handling the end the result in that function or bringing it back to my "main function"? I am aware this is probably an ambiguous question so I have posted my code here to try and help matters.
The program simply adds a string to a vector but I am wondering whats the best approach to handle it.
Thank you so much in advance.
Program 1.
std::vector<std::string> favouriteGames; //Stores favourite games
int menu = 0; //Menu navigation
std::cout << "1: Add Game. 2: Remove Game. 3: List Games. 4: Exit.";
std::cin >> menu;
//Menu
switch (menu)
{
case 1:
favouriteGames.push_back(AddGame());
break;
case 2:
//favouriteGames.erase(RemoveGame);
break;
case 3:
//ListGames();
break;
case 4:
break;
default:
std::cout << "Please enter correct data.";
}
//Add game
std::string AddGame()
{
std::string gameName;
int menu = 0;
std::cout << "Enter name of game you wish to add.";
std::cin >> gameName;
return gameName;
}
Program 2.
Or like this when the function is solely handling the data and doesn't return anything.
void AddGame(std::vector<std::string> favouriteGames);
int main()
{
std::vector<std::string> favouriteGames; //Stores favourite games
int menu = 0; //Menu navigation
std::cout << "1: Add Game. 2: Remove Game. 3: List Games. 4: Exit.";
std::cin >> menu;
//Menu
switch (menu)
{
case 1:
AddGame(favouriteGames);
break;
case 2:
//favouriteGames.erase(RemoveGame);
break;
case 3:
//ListGames();
break;
case 4:
break;
default:
std::cout << "Please enter correct data.";
}
//Keep Window open
std::string barn;
std::cin >> barn;
return 0;
}
//Add game
void AddGame(std::vector<std::string> favouriteGames)
{
std::string gameName;
int menu = 0;
std::cout << "Enter name of game you wish to add.";
std::cin >> gameName;
favouriteGames.push_back(gameName);
}
Program I.
In general, your functions should have one job. It makes them re-usable and helps to keep your interfaces clean and stable.
In this case, that means your function is actually named wrongly. It should be something like requestGameName().
You could then also hive the .push_back into its own, second function (addGame()?) though that may be overkill in your initial version. Still, one day, adding a game may involve more lines of code that trigger you to move all of that into another function.
I have written a program with several menus within it. I am now debugging the program and I wanted to include some input validation in the menu choices. However, for some reason, when it detects a wrong input it goes back to the beginning of the function with a goto statement (I know, bad practice :\) and It asks the user for a new input, but even if the input is right, it goes back to the case for non allowed inputs (default) no matter what. Does anyone have any idea of what's going on?
NOTE:
select_variable_check(vector<int> , int) is a function that checks if the value entered has been entered before if that is of any relevance, although I don't think it has anything to do with it.
void select(vector<int>&select_control) {
char select;
choices:
cin >> select;
int selectint = select;
bool check = select_variable_check(select_control, selectint);
switch (select) {
case ('1','2','3','4','5','6','7','8','9','10'):
if (check == false) {
string city = city_selection(selectint);
double xcoor = xcoor_selection(selectint);
double ycoor = ycoor_selection(selectint);
cout << "\n" << city << "\n";
select_control.push_back(selectint);
cout << "\n Enter next city: ";
cin >> select;
selectint = select;
}
else {
cout << "You have already selected that city, please select another one ";
cin >> select;
}
break;
case '99': {
cout << "TERMINATING" << endl;
Sleep(3000);
exit(0);
break;
}
case '100': {
cout << "input complete" << endl;
break;
}
default: {
cout << "not a valid value, please try again" << endl;
goto choices;
break;
}
}
The value of ('1','2','3','4','5','6','7','8','9','10') is '10', so that's the only value that will trigger that first case statement. The right way to write this is:
case '1':
case '2':
case '3':
...
Even with this change, though, '10' is a peculiar kind of character, and almost certainly not the right thing here.
Your code boils down to
start:
get_input
process_input
if good do something
else go to start
end:
Now when you enter bad input it goes back to start. Your input operation will fail again as the input stream is still in an error state so you do not get new input and since you have bad input you go back to start. To stop this loop you need to clear out the error flags on the stream and remove any input still in the buffer. That will make you default case look like
default: {
cout << "not a valid value, please try again" << endl;
cin.clear(); // removes error flags
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // flushes input buffer
goto choices;
break;
}
You will need to #include <limits> to use cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
After the call for Back to Main Menu, it returns to the mainMenu but when option or command is typed, the option is not accepted or the loop not working. Wonder where is the mistake? Is it extra call should be added or?
#include <iostream>
using namespace std;
char mainMenu(void);
int factorial(int n);
unsigned long long combination(long nK, long nR);
int main(){
char option;
int shape,function,i,j,k,t,n;
long nK, nR;
unsigned long long COM;
while((option=mainMenu())!='0')
{
switch(option)
{
case '1'://Program 1:
cout<< "*Drawing a shape\n"
<< "(1-Rectangle, 2-Triangle, 3-Inverted Triangle, 4-Letter 'H', 0-Back to Main Menu)\n";
do
{
cout<< "Choose shape >> ";
cin>> shape;
cout<< endl;
switch(shape)
{
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 0:
//Back to Main Menu
cout<< "Back to main menu\n"
<< endl;
return mainMenu(); //After here, it does back to Main Menu but command or option is not working
}
}while(shape!=0);
case '2': //Program 2
cout<< "*Choose function of calculator\n"
<< "(1-Factorial, 2-Combination, 0-Back to main menu)\n";
do
{
cout<< "Choose function >> ";
cin>> function;
cout<< endl;
switch(function)
{
case 1: break;
case 2: break;
case 0:
cout<< "Back to main menu\n"
<< endl;
return mainMenu();
}
}while(function!=0);
case '0':
cout<< "Program is terminating\n"
<< endl;
return 0;
default:
cout<< "Wrong input. Please choose one of the above options.\n"
<< endl;
return mainMenu();
}
}
}
char mainMenu(void){
char option;
cout<< "##############################\n"
<< "Main Menu\n"
<< "Enter your command!\n"
<< "##############################\n"
<< endl
<< "1. Program1\n"
<< "2. Program2\n"
<< "0. Exit\n"
<< endl
<< "Command >> ";
cin>> option;
cout<< endl;
return option;
}
I'm not sure what your question is, but your code is missing 2 important things. First, you need break statements at the end of each case block, otherwise the program flow will continue on to the next case statement.
Second, the inner menu doesn't ever escape the inner while(1) loop. This is a possible case for a goto use, although in practice it would better to refactor the code to split the top menu and inner menu into two functions, and use a return in the inner menu to return to the outer menu.
I'm not sure what your question is, but your code is missing 2 important things. First, you need break statements at the end of each case block, otherwise the program flow will continue on to the next case statement.
Second, the inner menu doesn't ever escape the inner while(1) loop. This is a possible case for a goto use, although in practice it would better to refactor the code to split the top menu and inner menu into two functions, and use a return in the inner menu to return to the outer menu.
As said, you're code is missing various things. It would be awesome if you distribute the entire code, and additionally the exact error message with line.
void value not ignored as it ought to be?...
...Is not that much of an explanation...
Also, are you sure you included iostream?
#include iostream
That said, you did not declare any of the variables used in the program.
You also missed a space in line 2 of your mainMenu() function.
Also, please tell us what you expected to happen.
So i'm making a menu in a simple console app.
My code is pretty much: (LINKS TO ACTUAL CODE AT THE BOTTOM!)
int input;
bool LOOPING = true;
while(LOOPING)
{
cout << "Select an option:\n";
cout << "1 - option 1\n";
cout << "2 - option 2\n";
cout << "3 - option 3\n";
cout << "4 - option 4\n>";
cin >> input;
switch(input) {
case 1:
game();
break;
case 2:
game();
break;
case 3:
game();
break;
case 4:
game();
break;
default:
cout << "ERROR: invalid input!\nPlease enter in a number!\n\n";
break;
}
}
// rest of app...
My problem is, the program just goes into a constant loop of text! Why is this happening? Why does default: not stop that from happening and how do i stop this from occuring?
Thanks in advance!
EDIT: asked for real code.
http://pastie.org/2415852
http://pastie.org/2415854
http://pastie.org/2415855
Your code is looping infinitely because you never set LOOPING to false. In the real code you only set it to false when the user chooses to exit, which will never happen because the user is not able to enter input anymore after he inputs a non-number for the first time.
The reason that it doesn't keep asking you for input after you entered a character is that >> does not consume invalid input. I.e. if >> is supposed to write into an int, but what the user enters is not a valid int, it will not write to the int, but it will also not remove the user input from the stream (instead it will simply set cin's error flag, which you should check).
The input will stay in the stream until you write it somewhere else or discard it. Until you do that every subsequent attempt to read an int will fail because the invalid input is still in the stream.