C++ While Loop Clarification - c++

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.

Related

Why can't we use the same logical operator (AND/OR) for the same situation (input "Q"/"q") in "if" and "while"?

#include <iostream>
#include <vector>
using namespace std;
int main() {
char selection {};
do {
cout<<"\n---------------"<<endl;
cout<<"1 do this "<<endl;
cout<<"2 do that "<<endl;
cout<<"3 do something else "<<endl;
cout<<"q Quit "<<endl<<endl;
cout<<"Enter your selection : ";
cin>>selection;
if (selection=='1')
cout<<"You chose 1 -- doing this "<<endl;
else if (selection=='2')
cout<<"You chose 2-- doing that "<<endl;
else if (selection=='3')
cout<<"You chose 3-- doing something else "<<endl;
else if (selection=='Q'||selection=='q')
cout<<"Goodbye! "<<endl;
else
cout<<"Unknown value --try again "<<endl;
} while (selection!='q'&& selection!='Q');
cout<<endl;
return 0;
}
You are wondering why the two conditions, while semantically describing the same end situation use opposite operators (AND vs. OR).
if (selection=='Q'||selection=='q')
/* ... */
while (selection!='q'&& selection!='Q')
They can use the same operator, if you correctly invert it.
I.e.
if ( (selection=='Q' || selection=='q'))
/* ... */
while (!(selection=='q' || selection=='Q'))
or
if (!(selection!='Q'&& selection!='q'))
/* ... */
while ( (selection!='q'&& selection!='Q'))
(I was a little generous with the () to be more suggestive, obviously a few of them are not needed.)
Because the first one is an inversion of the second one.
You want to do something "if" and you want to loop "while not".
Just as a lateral solution, as long as you do not have a break anywhere in the loop, you can move the "Goodbye" out of the loop and unconditionally execute it afterwards. Then you check the end condition only once, instead of twice. In my opinion this improves readability and maintainability.
Why can't we use the same logical operator (AND/OR) for the same situation (input “Q”/“q”) in “if” and “while”?
Because it is not the same situation. Why? Let's see:
else if (selection=='Q'||selection=='q')
Above code says, If this condition is true, that is if selection is q or Q, then exit.
while (selection!='q'&& selection!='Q')
And this one says, if the condition is not true, keep looping.
You can still use || or && in both conditions if you want. For example, both of the following are equivalent:
while (selection!='q'&& selection!='Q')
//
while( !(selection == 'q' || selection == 'Q') )
See the answer by Yunnosch for more details on this.

do ... while loop not breaking c++

currently I'm having problems with this do ... while loop.
do {
// program code here
cout << "Would you like to run the program again?(yes/no)";
bool exit = false;
string strexit;
do {
getline(cin, strexit);
if (strexit == "no") {
exit = false;
break;
}
else if (strexit == "yes") {
exit = true;
}
else {
cout << "Enter yes to rerun the program, and no to exit.\n";
};
} while (!exit);
system("cls");
} while (exit);
return 0;
}
I researched online, how to break out of do ... while loops, and it's when the condition is true, it loops back again, but if its false it exits.
So if you look at the code, if the user types in no, it sets exit = false, which takes it out of the bigger do while loop, where the break takes it out of the current do while loop.
If the user enters yes, it changes exit to true, which breaks it out of the current do ... while loop, but it doesn't break out of the second.
My question is, (or what I need help with) is that when the user inputs 'no', it cannot exit the do ... while loops, and I'm severely confused as to why. (It loops back to the beginning of the program.)
In the (shortened) code
do
{
bool exit = false;
// ...
} while (!exit);
you actually have two different symbols named exit. Inside the loop you have the variable. Outside of the loop, and used for the condition, you have the function std::exit. Which will be plain exit if you have using namespace std;.
The function exit when used in the condition will decay to a pointer to the function, and it will never be "false". So the condition !exit is always true and you have an infinite loop.
To solve this there are two things you need to do:
Learn that using namespace std; is very bad practice
Move the variable exit to be defined outside the loop. And you should really rename to something more descriptive it as well (the word "exit" is a little bit to general).
I think #SomeProgrammerDude has given excellent advice that's well worth following--but I'd go a step further, and advise moving the code to get the user's response into a separate function so you can more easily reason about each part of the code in isolation:
bool check_for_exit() {
std::string prompt = "\nDo you want to exit the program? ";
std::string strexit;
do {
std::cout << prompt;
std::getline(std::cin, strexit);
prompt = "\nPlease enter yes or no";
} while (strexit != "yes" && strexit != "no");
return strexit == "yes";
}
Then you use that function in the code that does the real work, something on this order:
do {
whatever();
} while (!check_for_exit());
It seems to me that this approach helps avoid many of the problems you encountered in your code.

Infinite Loop When Using Function Return Value as a Statement [duplicate]

This question already has answers here:
What is a debugger and how can it help me diagnose problems?
(2 answers)
Closed 5 years ago.
Was making a small code for a text based game but i tried to do thinks a bit different than the tutorial sort of to test my understanding but i tried to get a function value to make a do while statement but it seems whether the statement false or true the code just keep looping infinitely im a beginner so pls if you have a time explain why the code is faulty and Thank you in Advance
The main function
int main() {
PrintIntroStart();
do {
PlayGame();
AskToPlayAgain();
} while (AskToPlayAgain() == true);
return 0;
}
the Bool Function
bool AskToPlayAgain(){
//Asking The Player Whether To Play Again Or Not
std::string PlayerResponse = "";
std::cout << "Do You Want To Play Again? (Yes/No)" << std::endl;
std::cin >> PlayerResponse;
if (PlayerResponse[0] == 'y' || 'Y')
return true;
else
return false;
}
Also, here you are asking twice to play again
do {
PlayGame();
AskToPlayAgain();
} while (AskToPlayAgain() == true);
this should be
do {
PlayGame();
} while (AskToPlayAgain() == true);
if (PlayerResponse[0] == 'y' || 'Y') this one should be
if (PlayerResponse[0] == 'y' || PlayerResponse[0] == 'Y')
Otherwise your if condition is always true, because 'Y' itself is non-zero.
And in fact you don't need this if statement, just
return PlayerResponse[0] == 'y' || PlayerResponse[0] == 'Y';
So first of all, you are only checking the outcome of the game every second play.
You should follow #ziza s answer and remove the function call inside the loop.
The second problem, that causes the infinite loop is your input check.
A bool value in c++ is not a single bit, but just anoter regular value that is evaluated as false if it is 0 and to true if it has any other value. In your case the first comparison will evauate to 1 if the player input is 'y' and the second part of the condition will be the value of the 'Y' character (which is not 0). So your condition will always be true like #liliscent stated.

While function doesn't work like I want it to

Had a new problem with the while function. As easy as it sounds, I still can't wrap my head around it.
Like my last program, this one closes unexpectedly after the correct and wrong messages.
I want this to loop after entering a number, so that the program won't stop.
Thanks for the help, if any.
#include <iostream>
using namespace std;
int main()
{
int X = 0; //setting the first variable
int num; //setting the second
while (X == 0) //this should happen whenever X is equal to 0
{
cout << "Type a number bigger than 3. "; //output
X++; //This should increase X, so that the next while function can happen
}
while (X == 1) //again, since I increased x by one, (0+1=1 obviously) this should happen
{
cin >> num; //standard input
if (num > 3) //if function: if num is bigger than three, then this should happen
{
cout << "Correct! Try again!" <<endl; //output
X--; //Here I'm decreasing x by one, since it was 1 before, now it becomes 0. This should make the "while (X == 0)" part happen again, so that another number bigger than three can be entered
}
if (num <= 3) //if function: if num is lesser than or equal to 3, this should happen
{
cout << "Wrong! Try again!" <<endl; //output
X--; //This is supposed to work like the "X--;" before, repeating the code from "while (X==0)"
}
}
}
now it becomes 0. This should make the "while (X == 0)" part happen again
Nope. While loops don't magically take effect at any point during execution of the program. You only enter a while loop when you've reached it from code above. Programs are executed top-to-bottom, generally.
You would need a loop around the entire program if you want to keep going round and round. Those whiles you have now should probably be ifs.
Merge the two while loops into one, while(true).
Put each previous while body into an if state with the clause from the old while in it.
while(true) {
if (X==0) {
// the X==0- case
} else if (X==1) {
// the X==1 case
}
}
in order to end your loop, do a break;.
You have to think of C++ programs as a sequence of instructions, like a recipe. while just means a loop: you check the condition. If true, you run the body. After running the body, you check only that condition again, and run the body if true. Whenever the condition is false at the start or end of the body of the while (the {} enclosed code after it), you end the loop and proceed to the next one.
The first loop runs, finishes, then the second loop runs in your code. Once the first loop exits, you do not go back into it just because the condition becomes true.
Understanding flow control is one of the "hard" steps of learning to program, so it is ok if you find this tricky.
There are many improvements you can do your code beyond getting it working -- there is, actually, little need for X at all. But baby steps! Once you get it working, you can ponder "how could I remove the variable X?".
Before making such fundamental changes to your program, you should get it working, and save a copy of it so you can "go back" to the last working version.
You want to wrap all that code in it's own while loop:
while (true /* or something */)
{
while (X == 0) //this should happen whenever X is equal to 0
{
// ...
}
At least put your second while loop inside the first one to get it working as intended. Otherwise your program has no reason to go back again.
Nevertheless it's not a good design.

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;
}