how to loop in nested if else statement - c++

we are currently creating a mini game for our school project.
the game code is already done but im currently doing some introduction.
i was thinking of putting the mechanics of the game when you run the program and i want to put a menu.
ex.(press 1 to play , press 2 to exit) im already done with the code for the nested if too but i don't know the code for looping it back to asking a number if the user enter a number that's not indicated for example the number 3. I want to loop it back to asking a number until the user input a valid number.

If you are trying to exit the "if" statement, I think you want to use:
continue;
If you are in a switch/case, you would use:
break;

Just create a level.Then if your input doesn't satisfy the conditions ,then jump that level again using goto level and take input again untill it satifies the conditions.
karim:
int a;
cin>>a;
if(a==1){....do what...}
else if(a==2) { ...do what...}
else
goto karim;

Just put all of your actions in a while() cycle and write something like that:
while ((key = getch()) != *exit key*){
if (key == ...){ action 1; }
else if (key == ...){ action 2; }
else if (key == ...){ action 3; }
}

Related

C++ While Loop Clarification

This is the coding I have for my while loop, all I want is for the program to ask the user if they want to re run the program. The are supposed to enter (Y/N). However each time I run my program it just continually runs the main() function, even if I enter a N or n character for my ans variable. Any help would be greatly appreciated.
cin>>ans;
while((ans !='N')||(ans !='n')) {
return main();
}
return 0;
}
In your while statement, the "||" means "or". As long as one of those conditions are true, the while statement will keep running. You need to use an "and" statement, "&&".
This condition (ans !='N')||(ans !='n') is always true. Either ans is not N or ans in not n. One side is always true. Change it to while (ans !='N')&&(ans !='n') then your loop terminates if ansis equal N or ans is equal n.
Note A || B is the same as !(!A && !B).
Proper way
int askAgain() {
do {
// Do your work
// But never call main(), people will laugh
cin>>ans;
} while((ans !='N') && (ans !='n'));
return 0;
}
There are better ways to accomplish what you're seeking to do. Even though it may be possible to make it work with return main(), it's highly inefficient.
One way to have a loop that runs until the user enters a key ('N' in this example) would be to:
int main()
{
char ans = '?';
while (ans != 'N' && ans != 'n')
{
cin >> ans;
}
return 0;
}
The intention is to continually prompt the user to enter a value once it doesn't match the condition. I've also set 'ans' to a value '?' so that on the first run of the loop it won't encounter an error. You could also turn this into a: do-while loop and remove the initialization to accomplish the same thing.
Hope that explains it enough for you.

I have an error with my return statements that I don't know to fix

In a text adventure game that I am making, all the different places are run my different functions. In my diner, market, and supply store, I have a switch statement that takes numbers 1-10. All 1-9 work, but 10 doesn't. All of these methods return back to a method called TownCenter(), but on these 3, when I do return, you have to spam it in order for it to work. Here is a code example:
void Diner(){
int answer;
cout << "Blah, blah. Type '0' to go back to town.\n";
cin >> answer;
switch (answer){
case 0:
return;
break;
}
Diner()
}
Every time you type 0, it would just go to Diner() again. It eventually works if you spam 0 over and over, but why won't it work all the time?
I don't think there is any error with the code, except for the following considerations:
Missing semicolon after Diner() in line 10.
The break; statement is not required as return; is being used before it.
I don't think you mean to use recursion here. I would suggest using while loops while people are in individual locations. By calling the same location again at the end of your case statement to go back to the same area, you are going deeper in the callstack, requiring more "exits" to "leave" the room.
A do-while loop like the following would work nicely:
int answer;
do {
cout << "Blah, blah. Type '0' to go back to town.\n";
cin >> answer;
switch (answer){
// other case statements
case 0:
break;
}
} while (answer != 0);
Notice I don't call Diner() again at the end. Getting it to process the same room until the "leave" is accomplished by the loop instead of unnecessary recursion.

C++ Input Validation to avoid ability to break code

I have written a program that simulates a fishing game. The program is inside a running loop to iterate as long as the user wishes. The issue is that anything that is entered, other than 1 or 0, breaks my code. I have been trying different things for hours now, and I need some help! My main cpp file code is included. Please let me know if my header files are needed for your review as well.
It has been requested for me to edit the code. The problem is that anything other than an integer breaks my code when entered. I do not want this. I want the program to catch the input and continue looping until the user enter's the right input ( 1 or 0) or quits the game.
Game game; // Game object game declared
cout<<"Welcome to Go Fish 2.0!"<<endl; // welcome message
cout<<"Would you like to play?"<<endl; // Prompts user to play
cout<<"1 to play, 0 to exit:"<<endl; // Provides user with input choices
cin>>choice; // user enters game play choice
if (choice == 1) // while user chooses to play game
play = true; // play boolean is set to true
else if (choice == 0) // while user chooses to end game
play = false; // play boolean is false
while ( ! cin>>choice) { // while user entry is not valid
// display correct inpout choices again
cin.clear();
cin.ignore (100, '\n');
cout <<"You entered invalid data. Please enter the numerical value 1 if you want to play again or 0 if you dont."<<endl;
cin >> choice; // hopefully user enters valid input
if (choice == 1) { // if user chooses proper input after improper input
play = true;// play boolean is set to true
break;// break
}
}
total=0; // variable total is initialized to 0
while (play == true) { // while play boolean is set to true; user wants to play game
total1 += game.playgame(total); // total1 variable keeps a running total of the game
//game.playgame(total) uses the game object to call the playgame function that passes the variable total
// when game.playgame(total) is called this funciton essentially mobilizes game play of die rolling and point accumulation
//each time this function is called (as many times as user wants to play game), the running total is incremented
cout<< "Do you want to play again? (0 for no, 1 for yes)"<<endl;// asks user if they want to play again
cin >> choice;// user enters choice
if (choice == 1) // if user enters 1
{
play = true; // play is assigned to true
}
else if (choice == 0) // if user enters 0
{
play = false; // play is assigned to false
}
/*
while ( ! cin>>choice) { // while user entry is not valid
// display correct inpout choices again
cin.clear();
cin.ignore (100, '\n');
cout <<"You entered invalid data. Please enter the numerical value 1 if you want to play again or 0 if you dont."<<endl;
cin >> choice; // hopefully user enters valid input
if (choice == 1) { // if user chooses proper input after improper input
play = true;// play boolean is set to true
break;// break
}
}
if (choice == 1) { // if user chooses proper input after improper input
play = true;// play boolean is set to true
break;// break
cout<<"My Total game points are "<<total1<<endl; // displays user's total points from whole game
if (total1>100) // if game total greater than 100
cout<<"Awesome! You're a great fisher!"<<endl; // congratulate user
if (total1<100)// if game total is less than 100
cout<<"Good job, but play again so you can fish some more."<<endl;// chastise user
system("pause");
}
}
return 0;// end main function
}
}
You should take input from the user as a string/character array first and then attempt to convert it to an int (there are a number of ways to do this - Google is your friend ;)) but atoi (ASCII to int) is probably the quickest/simplest. If that fails, ask the user to enter a valid input, repeat until you get a 1 or 0, something like that.
There are multiple places where you expect input. I couldn't make much sense of your code.
Based on your description you just need one place to read the integer: a loop reading the choice and verifying the correct input was received. That should be rather straight forward...
for (int choice(0); true; ) {
std::cout << "some message goes here\n";
if (std::cin >> choice) { // successfully read a value
if (choice == 0) { // the choice is to stop
break;
}
else if (choice == 1) { // the choice is to carry on
play_again();
}
else { // an invalid choice was made
std::cout << "value " << choice << " is out of range\n"
}
}
else if (std::cin.eof()) { // input failed because nor more input
break;
}
else { // a non-integer was entered
std::cout << "a non-integer was entered\n";
std::cin.clear(); // clear error state and ignore current line
std::cin.ignore(std::numeric_limits<std::streamsize>::max();
}
}

Getting stuck in an infinite loop

I had my program running smoothly, and then after commenting it and adding some final touches, it stopped working on me. The function that I am having problems with is using several objects/functions defined elsewhere, so I am just wondering if someone can affirm that my logic is correct and that the infinite loop is not a product of a syntax error. Thanks for your time, here is the problem I'm having:
If the cashier started a new order and wants to close his order, T is typed in. However, when trying to exit an order and loop back to the start of while(moreCustomers), nothing is happening. I am trying to exit the while(moreItems) loop by setting moreItems = false;, but after doing that, it gets stuck in the while(moreItems) loop and does not go back to while(moreCustomers). Does the syntax make sense, and should I be able to break the loop by setting moreItems = false;?
bool moreCustomers = true;
while (moreCustomers)
{
// get input to start new order or close register
drawInstruct("Enter N to start a new order or E to\n close the register.");
char* setFmt = "#"; // the input must be a letter
char input[7]; // char array that stores input from cashier
s.GetStr(xLeftCoord + 1, yTopCoord + 1, input, 1, setFmt, true);
for(int x = 1; x < 10; x++) // clear the input field
{
s.ClearScreenPos(x, 1);
}
if (input[0] == 'N') // if a new order is requested
{
bool moreItems = true;
while (moreItems)
{
getInput(input);
if(input[1]) // if input is not a single char
{
if (input[0] == 'M') // get the desired number of multiples for the current item and update the tape and display area accordingly
{
custTape.handleMultiples(atoi(input)); // adds multiples to tape
curVal = isUPC->price * (atoi(input)); // updates the current item price
drawDisplayArea(curVal); // updates the display area
}
else // invalid number of multiples, prompt for new multiple
{
drawInstruct("Invalid command. Please try again.");
s.Delay();
}
}
else if (input[0] == 'T') // close the order
{
drawInstruct("Order cancelled.");
s.Delay();
moreItems = false; // customer order is complete, exit loop
}
else // invalid command, get new input from the cashier
{
drawInstruct("Invalid command. Please try again.");
s.Delay();
}
}
}
else if (input[0] == 'E') // close the register
{
moreCustomers = false; // no more customers, exit the program
}
else // invalid command, get new input from the cashier
{
drawInstruct("Invalid Command. Please try again.");
s.Delay();
}
}
I can't exit else if(input[0] == 'T'), and any commands I enter in after moreItems = false; work correctly.
I'd set a breakpoint on the first moreItems = false; line to see if it is ever being hit. My guess is that it is not. You've tagged the question with Visual Studio, so if that is what you're using see this link for how to set a breakpoint:
http://msdn.microsoft.com/en-us/library/vstudio/k80ex6de%28v=vs.100%29.aspx
Basically a breakpoint causes your program to stop at that line. Also try setting a breakpoint on this line:
if (input[0] == 'N')
Run the program, press a key, and wait for the breakpoint to be hit. Then use the "Step Over" option on the Debug menu. This runs your program line by line, each time you press "Step Over" (F10 does this too, much quicker). Keep stepping to see what path of execution occurs through your code. You may also be able to hover over variables to see their values.
Theres loads on the net about debugging with visual studio, but if you master the above you'll be well away

Infinite Loops and Early Return Statements

I have a simple console application that outputs a menu and waits for user input. After performing the appropriate action, the entire process repeats. The program exits when a specific string is entered. This is implemented with an infinite loop and an early return statement:
int main()
{
while (true)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") return 0;
}
}
According to my teacher, it's bad practice to use an infinite loop and hack my way out of it with a return statement. He suggests something like the following:
int main()
{
bool ShouldExit = false;
while (!ShouldExit)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") ShouldExit = true;
}
return 0;
}
Is it really a bad idea to use an infinite loop and an early return statement?
If so, is there a technical reason or is it just bad practice?
This might be one of those rare cases where do...while is appropriate. I avoid adding extra boolean state variables unless they genuinely make the code clearer.
int main()
{
string UserChoice;
do
{
OutputMenu();
cin >> UserChoice;
// ...
} while (UserChoice != "exit");
}
However, for a user input loop I would usually make a function that returns whether or not the input was successful. As it stands the code could easily end in an infinite loop if cin closes.
E.g.
bool GetNonExitInput( std::istream& in, std::string& s )
{
OutputMenu();
in >> s;
return in.good() && s != "exit";
}
int main()
{
std::string UserChoice;
while (GetNonExitInput(std::cin, UserChoice))
{
// ...
}
}
Really either is fine, but you need to do what your professor wants. You'll find it is the same in industry as well. Some companies may have a coding standard that dictates curly braces go on a new line, while others want them to start on the line that begins the block. There is no real reason to prefer one over the other, so it is best to just go with what the lead wants.
The only difference between these two approaches is that in the second approach you can still do something after you exit the while loop, while in the first approach, you're returning from the function itself; you can do nothing after the while.
However, I would suggest this simple code : instead of maintaining a variable, you can also use break like this:
while (true)
{
//your code
if (UserChoice == "exit")
break;
//your code
}
The variable ShouldExit is not needed anymore!
Depends on the language. If you're writing in C, then the "one entry, one exit" philosophy makes sense -- you want one place where you're cleaning up resources used by a function so that you don't have a chance of forgetting later. If you're in C++, then you should be using RAII for cleanup anyway, in which case I completely disagree with your teacher. Use returns as needed in order to make the code as clear as possible.
(Though I would use for (;;) instead of while (true) in C++ to generate the infinite loop)
With the controlled variable you would be able to handle exit conditions (code after the while) before exiting the function.
In my opinion both ways are fine, but the second one is "prettier".
In programing it is important to write the code in the easiest way you can think of, and make it simple for other programmers to understand your code if you'll be replaced or for any other reason.
There is no complexity issue involved with your two codes so they are both fine as I said, but the think I don't like about the first code is the use of 'return' statment without any real need of 'return' statment here.
There is another way writing this code, better then your way (in my opinion), but not better as your teacher's one.
int main()
{
bool ShouldExit = false;
while ( true )
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "exit") break;
}
}
Another main reason why I don't like your first code and my code above is because of the use of infinite loop, when you make yourself used to infinite loops it is just a matter of time until you will make your more complicated programs with major bugs in it.
Again - all of the things I wrote are in my opinion only and not gospel truth.
Rotem
Technically, there's not much in it, as long as there's no code you're skipping over via the use of the return.
However, your teacher's suggestion is more readable, if only because of the obvious meaning of "ShouldExit".
I think what your teacher means that the exit condition can easily maintained. This because of code cleanup after the while loop. If you will do a hard return then everything after the while loop will not be executed. This can prevented by using a break instead of return.
int main()
{
//create a file
while (true)
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
//write UserChoice to file
// ...
if (UserChoice == "exit") return 0;
}
//close file
}
//close file will then not be executed!
The break statement is specifically for exiting loops.
I would usually prefer what your teacher suggested, simply because it's easier to read and understand what are the conditions to stop the loop.
If you have an infinite loop with a return statement it's a little bit more difficult for someone who didn't write the code to go through the code and figure out when the program will hit a return statement.
Also I usually don't like early returns in general because it's easy for someone maintaining the code to introduce bugs, for example:
int main()
{
// code added by some other programmer:
importantInitialization();
while (true)
{
OutputMenu();
// code added by some other programmer:
Something *st = new Something();
string UserChoice;
cin >> UserChoice;
// ...
if (UserChoice == "a") runA();
else if (UserChoice == "b") runB();
else if (UserChoice == "c") runC();
else if (UserChoice == "d") runD();
else if (UserChoice == "exit") return 0;
else if (UserChoice == "help") showHelp();
// code added by some other programmer:
delete st; // this would not run on the last loop
}
// code added by some other programmer:
importantCleanUp(); // this would never run
}
of course that in this particular case it's easy to see the problems, but when maintaining a more complicated function you can see how an early return statement might make it even more prone to lack-of-attention bugs like this.
I think the while(true) with break is best for a few reasons. Introducing a variable to store the exit condition is error prone, more variables means more can go wrong. Also the break statement is meant specifically for breaking out of loops. Lastly, contrary to for(;;), while(true) is clean, readable, and concise, where for(;;) is trying to be clever for no good reason.
For an added point, to enhance readability and comprehension put the exit condition(s) nearest to the top of the loop as possible:
while (true) {
OutputMenu();
string UserChoice;
cin >> UserChoice;
if (UserChoice == "exit")
break;
// process other options here
}
A routine which uses a local flag is, in terms of state analysis, equivalent to the same code, copied out twice, with one copy corresponding to the flag being true, and the other copy being equivalent to the flag being false, and any code which changes the state of the flag jumping between them. If there are n flags, the equivalent would be 2^n copies of the code (though if some flags are mutually exclusive, some of those may be unreachable and irrelevant).
While there are certainly times that flags are the most practical way to do things, they add complexity to the code. When the complexity is really necessary, flags may be the cleanest way to provide it. When there's a clean and practical way to write code which avoids the flags, one should do so. There are certainly times when it may be unclear whether it's better to use or avoid a flag (e.g.
flag = condition_which_must_be_tested_here();
action_which_will_disturb_the_condition();
if (flag)
do_something();
else
do_something_else();
versus
if (condition_which_must_be_tested_here())
{
action_which_will_disturb_the_condition();
do_something();
}
else
{
action_which_will_disturb_the_condition();
do_something_else();
}
but in cases where no code can be written without a flag and without having to duplicate anything, such a version is generally preferable.
I'm philosophically opposed to while(true). It means "loop forever" and you never really want to loop forever.
On the other hand I'm also philosophically opposed to boolean variables that merely record state that can be found out in other ways. There's a bug in waiting in that it may not always be correctly synchronised with the state it is supposed to reflect. In this case, I'd prefer code like:
int main()
{
string UserChoice = "not started"; // or empty string
while (UserChoice != "exit")
{
OutputMenu();
string UserChoice;
cin >> UserChoice;
// ...
}
return 0;
}