I solved this with a loop but in the process I couldn't get the goto to work as expected.
This ends in an infinite loop. Obviously the last if statement is the culprit but how? If I press "n" or "y" it still stays in the loop. Play_again is a flag that tells the outer loop to stop.
1 2 3 4 5 6 7
re_ask:
cout<<"Would you like to play again? ";
cin>>again;
if (again=='n'){play_again = 0;}
if (again=='y'){play_again = 1;}
if (again!='n' || again!= 'y'){goto re_ask;}
Thanks. I have a loop, but wanted to complete the goto as a thought exercise. I had a lot of loops and wanted to simplify it a little. My loop...
1 2 3 4 5 6 7
while(flag){
cout<<"Would you like to play again? ";
cin>>again;
if (again=='n'){play_again = 0;flag = 0;} // play_again terminates another loop
if (again=='y'){play_again = 1;flag = 0;}
if (again!='n' || again!= 'y'){;}
}
Peter 87 I don't see where the third statement is always true. It will only be true if again is not "n" OR not "y". If user puts in a nonsensical response the program is redirected to asking it again until a sensical response is obtained.
#include <iostream>
usingnamespace std;
int main()
{
char again = '0';
re_ask:
cout<<"Would you like to play again? ";
cin>>again;
if (again=='n'){cout << "play_again = 0" << endl;}
if (again=='y'){cout << "play_again = 1" << endl;}
if (again!='n' || again!= 'y'){cout << "re-ask" << endl; goto re_ask;}
return 0;
}
Would you like to play again? x
re-ask
Would you like to play again? y
play_again = 1
re-ask
Would you like to play again? n
play_again = 0
re-ask
Would you like to play again? 0
re-ask
Would you like to play again?
play:
// play game
ask:
char again ;
std::cout << "again (y/n)?" ;
std::cin >> again ;
if( again == 'y' || again == 'Y' ) gotoplay ;
elseif ( again == 'n' || again == 'N' ) gotofinish ;
elsegotoask ;
finish:
std::cout << "bye!\n" ;
// end program
The thing that trips people up with loops like this is that the exit condition is in the middle of the loop, not the beginning or the end. Rather than fighting it, just code it that way. The general pattern is
1 2 3 4 5 6 7
while (true) {
get the input
if (input is valiid) {
process input
break;
}
}
In your case:
1 2 3 4 5 6 7 8 9 10 11
while (true) {
cout<<"Would you like to play again? ";
cin>>again;
if (again=='n'){
play_again = 0;
break;
} elseif (again=='y'){
play_again = 1;
break;
}
}
bool play_again()
{
char again ;
do
{
std::cout << "Would you like to play again (y/n)? ";
std::cin >> again ;
again = std::tolower(again) ;
}
while( again != 'y' && again != 'n' ) ;
return again == 'y' ;
}
#include<iostream>
usingnamespace std;
int main()
{
char again;
bool flag(1), play_again(0);
while(flag){
cout<<"Would you like to play again? ";
cin>>again;
if (again=='n'){play_again = 0;flag = 0;} // play_again terminates another loop
if (again=='y'){play_again = 1;flag = 0;}
//if (again!='n' || again!= 'y'){;}
}
//---> remove bottom line above
cout<<"out";
return 0;
}
Would you like to play again? f
Would you like to play again? s
Would you like to play again? m
Would you like to play again? y
out
dhayden thx for posting
The thing that trips people up with loops like this is that the exit condition is in the middle of the loop, not the beginning or the end. Rather than fighting it, just code it that way. The general pattern is
sage advice
are break commands well accepted in the programming community for programming flow and control? I don't mean this in the pejorative, I just have no idea.
Ideally this code could be dispatched as a function, predicated on a switch statement or a series of whiles and/or breaks.
I am not trying to be harsh or rude or anything, but:
I would advise abandoning messy, non-scalable, ugly & error prone statements like the ones you have on line 6, and follow what Duoas has said :+)
Messy, ugly and probably error prone I see; but non-scalable? : )
> are break commands well accepted in the programming community
I guess it largely depends on the specific subset of the 'programming community'.
Of the four jump statements (break, continue, goto and return), the only ones that are universally accepted without reservations are return and break within a switch statement.
The jump statements which unconditionally transfer control to another statement in the current function (continue, goto and break within an iteration statement) are often looked upon less favourably. Contexts in which use of one of these is the best available option are somewhat rare; of the lot, contexts in which goto is the best available option are extremely rare.
A much better option IMO, is a switch which is scalable - one could have say 20 or 100 cases in a switch. Particularly the default case, which does the same job as the messy if statement.
An example of this might be a program to convert assembly op-codes and their arguments to binary. There is an enum and a case for each op code.
JLBorges has a short version in his code above, but that only deals with a y / n question, I wouldn't have anything more than that. It could still be done with a switch - there are 3 cases: y, n or default for bad input.
We can always rely on you to provide an excellent and elegant answer :+)
Although the example I had in mind was stuck in ancient history - the op-code to binary thing was in C for a school boy type assignment. So rather than implement a find algorithm, it was easier to have massive enum, switch and a function for each one as well. Reading the code for the switch wasn't so bad, because each case called a function. There was another function which converted register names to numbers.
But your code is much better with c++, it's easy to see how that could be extended to use a std::vector<std::tuple<std::string, std::string, std::function>> to take care of op-codes and their arguments and a function to process them.
are break commands well accepted in the programming community for programming flow and control?
In addition to whay JLBorges has said, I'll add that if using a break or return makes the code cleaner and easier to read, then by all means use it. I've seen "purist" code that avoids breaks, insists on one return statement per function, and is nearly impossible to read as a result.
Not a particularly palatable idea; try reading code which has a switch with 20+ cases.
Quite true. In cases like this, I've used a table of function pointers instead.