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.
Related
Can someone explain the purpose of having two different types of while loops? I am new to programming. Also supply example situations with the proper while loop if possible.
I understand how to use a while loop. This is what I made:
bool myBool = true;
int i = 0;
while (myBool) {
if (i > 10) {
myBool = false;
}
i = i + 1;
}
A while loop will only execute when the boolean condition is true.
while (true) {
// INSERT CODE HERE
std::cout << "boolean condition is true - inside my while loop";
}
A do while whill check the boolean condition after the loop executes once.
do {
// INSERT CODE HERE
std::cout << "inside my while loop regardless of boolean condition";
} while (true);
Explicitly: the do while loop is guaranteed to execute at least once, whereas the while loop is not guaranteed to execute at all.
Similarly,
while (false) {
// INSERT CODE HERE
std::cout << "this will never execute";
}
will never execute and
do {
// INSERT CODE HERE
std::cout << "this will execute only once";
} while (false);
will execute once.
The do while loops are control flow statements, they execute a block of code at least once and then the iteration of loops depends on the condition which is checked at the bottom of the loop, They are best to use when you want at least once the loop to be executed, for ex
#include <stdio.h>
int main () {
int c = 50;
/* The do will be executed */
do {
printf("value of c: %d\n", c);
c = c + 1;
}while( c < 20 );//It will depend on the condition
printf("any string");
return 0;
}
Here is a Flow diagram of do while loop
Simple answer is while loop will execute only if condition inside of while statement is true.
do while loop will execute once regardless of the while statement condition.
#include <iostream>
using namespace std;
int main(int argc, char *argv[]){
int i = 1;
while( i < 1){ // this loop will never execute as 1 is not smaller then 1
i++; // if the loop was working we would get print 2 here
cout << i << endl;
}
cout << i << endl; // this one will print outside of loop value 1
do{
i++; // increase i to 2
cout << i << endl; // this will print 2
} while (i < 1); // This loop will execute at least once and as the condition of 2 is not smaller then 1 it will exit after one execution
return 0;
}
The difference between while and do-while is that in
while (<condition>)
{
//statements
}
we can control whether to enter the loop by using the test condition.
Whereas in
do
{
//statements
} while (<condition>);
the code has to enter the loop at least once before it can exit by using the condition.
So if we want to enter the loop at least once we should use do-while whereas if we want to test and decide whether to enter the loop or not, we have to use while.
To explicitly answer your first question:
Why does C++ have different kinds of loops? -> Legacy. Other languages (in particular, C) before C++ had this feature, so C++ chose to have it.
Why did other languages have it? -> This gets muddy, but a good explanation is that early languages often did not have optimizing compilers, so your code mapped quite directly to machine code. Providing various loop syntaxes allowed programmers to write structured code that still generates good machine code for their particular case.
In practice, it is rare to see a true do {} while () loop. This may be because for (or range-based for) and while () {} have strictly greater capabilities than do {} while (): An unconditional first loop iteration is possible with every loop, but the reverse is not true. In the very common case of iterating over a (possibly empty) sequence, having a guaranteed loop body execution like do {} while () is actually wrong.
There are plenty of answers with examples and explanations about the loops, so I won't bother repeating this here. I will add though that the most that I personally have seen do {} while () used is, ironically, not for looping but for this.
do-while loop performs the task before the condition in while(). It is for situations when you are trying to prompt the same thing for every wrong action (i.e., user authentication, wrong menu entry). On the other hand, a simple while loop performs till a condition is true (Note: In most cases people use for loops instead of while to define counter, initialize, set condition and increment/decrement - all in the same line).
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.
I want to check a condition inside a loop and execute a block of code when it's first met. After that, the loop might repeat but the block should be ignored. Is there a pattern for that? Of course it's easy to declare a flag outside of the loop. But I I'm interested in an approach that completely lives inside the loop.
This example is not what I want. Is there a way to get rid of the definition outside of the loop?
bool flag = true;
for (;;) {
if (someCondition() && flag) {
// code that runs only once
flag = false;
}
// code that runs every time
}
It's fairly hacky, but as you said it's the application main loop, I assume it's in a called-once function, so the following should work:
struct RunOnce {
template <typename T>
RunOnce(T &&f) { f(); }
};
:::
while(true)
{
:::
static RunOnce a([]() { your_code });
:::
static RunOnce b([]() { more_once_only_code });
:::
}
For a less convoluted version of Mobius's answer:
while(true)
{
// some code that executes every time
for(static bool first = true;first;first=false)
{
// some code that executes only once
}
// some more code that executes every time.
}
You could also write this using ++ on a bool, but that's apparently deprecated .
a possibly cleaner way to write this, albeit still with a variable, would be as follows
while(true){
static uint64_t c;
// some code that executes every time
if(c++ == 0){
// some code that executes only once
}
// some more code that executes every time.
}
The static allows you to declare the variable inside the loop, which IMHO looks cleaner. If your code that executes every time makes some testable change, you could get rid of the variable and write it like this:
while(true){
// some code that executes every time
if(STATE_YOUR_LOOP_CHANGES == INITIAL_STATE){
// some code that executes only once
}
// some more code that executes every time.
}
#include <iostream>
using namespace std;
int main()
{
int fav_num = 0;
while (true)
{
if ( fav_num == 0)
{
cout <<"This will only run if variable fav_number is = 0!"<<endl;
}
cout <<"Please give me your favorite number."<<endl;
cout <<"Enter Here: ";
cin >>fav_num;
cout <<"Now the value of variable fav_num is equal to "<<fav_num<<" and not 0 so, the if statement above won't run again."<<endl;
}
return 0;
}
OUTPUT
This will only run if variable fav_number is = 0!
Please give me your favorite number.
Enter Here: 1
Now the value of variable fav_num is equal to 1 and not 0 so, the "if statement" above won't run again.
If you know you only want to run this loop once, why not use break as the last statement in the loop.
1 while(true)
2 {
3 if(someCondition())
4 {
5 // code that runs only once
6 // ...
7 // Should change the value so that this condition must return false from next execution.
8 }
9
10 // code that runs every time
11 // ...
12 }
If you expecting the code without any external flag then you need to change the value of condition in last statement of the condition. (7th line in code snippet)
I have the following C++ code:
if(x==y||m==n){
cout<<"Your message"<<endl;
}
If x is equal to y or m is equal to n, the program prints "Your message". But if both conditions are true,the program tests only one of them and eventually prints one "Your Message".
Is there a way to print each "Your message" independently based on each condition using a single if statement?
The output would be identical to the below using multiple if statements.
if(x==y){
cout<<"Your message"<<endl;
}
if (m==n){
cout<<"Your message"<<endl;
}
Not that I'd ever do it this way, but ...
for(int i = 0; i < (x==y)+(m==n); ++i) {
std::cout << "Your message\n";
}
Let me expand on this. I'd never do it this way because it violates two principles:
1) Code for maintainability. This loop is going to cause the maintainer to stop, think, and try to recover your original intent. A pair of if statements won't.
2) Distinct input should produce distinct output. This principle benefits the user and the programmer. Few things are more frustrating than running a test, getting valid output, and still not knowing which path the program took.
Given these two principles, here is how I would actually code it:
if(x==y) {
std::cout << "Your x-y message\n";
}
if(m==n) {
std::cout << "Your m-n message\n";
}
Aside: Never use endl when you mean \n. They produce semantically identical code, but endl can accidentally make your program go slower.
I don't think that's possible. What you have inside your bracket is a statement which is either true or false, there's no such thing like a true/true or true/false statement. What you could do is a do/while loop with a break statement. But I don't think that's the way to go. Why do you want to avoid two if statements?
single "|" or "&" gaurantees both side evaluation even if the result can be determined by left side operator alone.
You could do something like this, to build up the "message":
string msg = "Your Message\n";
string buildSt = x == y ? m == n ? msg + msg : msg : m == n ? msg : "";
Compiler checks only one condition when both are true because you've connected your conditions with OR.
If even one condition in ORs chain is true there is no need to check others as a result already true and will be false if one of them is false. So if you think that your logic is right then there is no need to do multiple checks. Your code is asking that you will print a message if one of the conditions is true and program doing it. If you want something special for a case when both conditions are true then add it separately. Shortly you should never expect from the compiler to do all checks in the expressions connected by OR.
Regards,
Davit
Tested code:
#include <iostream>
#include <string>
using namespace std;
void main() {
int x=1;
int y=1;
int m=1;
int n=1;
string mess1="Your message 1\n";
string mess2="Your message 2\n";
cout<<((x==y)?mess1:"")+((m==n)?mess2:"");
getchar();
}
If you are trying to see if both statements are true an && is what you will want to use.
Take a look at Boolean Operators to see all of the possible options when comparing boolean (true/false) values.
To answer your question:
if ((x==y) && (m==n))
{
cout<<"Your Message"<<endl<<"Your Message"<<endl;
}
else if((x==y) || (m==n))
{
cout<<"Your Message"<<endl;
}
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;
}