-3

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.)

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 2
    Why do you have two while loops here? – Code-Apprentice Jul 06 '18 at 22:05
  • the first nested do while loop, is to make sure the user inputs the right answer (yes/no), so as you can see, it keeps on saying cout << "Enter yes to rerun the program, and no to exit.\n"; until the user inputs yes or no. The second while loop, is for the user to have the option to rerun the whole program again. Is there some easier way for the user to rerun the whole program? – AdamIsAProgrammer Jul 06 '18 at 22:08

2 Answers2

13

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:

  1. Learn that using namespace std; is very bad practice

  2. 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).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    I think a slightly better piece of advice here than avoiding `using namespace std;` would be "compile with warnings cranked up to max and treated as errors." On my machine, this produces a compiler error that immediately flags the issue, though I suspect on lower warning levels that this might not happen. – templatetypedef Jul 06 '18 at 22:11
  • 2
    A third suggestion. Don't use `exit` as a variable. Use `exitLoop`, perhaps. – R Sahu Jul 06 '18 at 22:12
  • 4
    For what it's worth, `-Wall` on g++ exposes the mistake with a warning. – Silvio Mayolo Jul 06 '18 at 22:13
  • thanks for the help! I'm fairly new to c++, and have never heard that using namespace std; was bad. Thanks for the advice! although I do believe having to write std::cout everytime I want to output something in c++ is going to be quite extensive. – AdamIsAProgrammer Jul 06 '18 at 22:15
  • @templatetypedef How do you make your machine produce a compiler error that immediately flags the issue? I'm currently using Microsoft Visual Studio. – AdamIsAProgrammer Jul 06 '18 at 22:16
  • @AdamIsAProgrammer There's an easy solution to that: `using std::cout;`. That pulls in just `std::cout` into the current namespace, not everything from `std`. Or just get used to prefix everything from the standard library with `std::` (it doesn't really take that much time of effort :) ) – Some programmer dude Jul 06 '18 at 22:16
  • Ah that makes sense, could you also use that for cin and string? such as using std::cout, std::cin, and std::string?. or you have to separate the lines? – AdamIsAProgrammer Jul 06 '18 at 22:18
  • @AdamIsAProgrammer You have to do it separately unfortunately. – Some programmer dude Jul 06 '18 at 22:18
  • "have never heard that using namespace std; was bad." -- See https://stackoverflow.com/q/1452721/2785528 – 2785528 Jul 07 '18 at 01:17
3

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.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Since, I'm still a new user to c++, I actually learnt about functions halfway through coding this project. So next time, I'd probably try to take it a step further and implement functions into my future projects. Thanks for the advice too though! – AdamIsAProgrammer Jul 06 '18 at 23:24