Besides the obvious inversion between && and || all the answers to the questions, let me go a little further to make another mistake obvious (in fact, not a mistake, but a design weakness): you ask yes or no, accept something, and if the answer looks yes, you exit. Everything else plays like no. Even "one cup of coffee."
And inverting the whole logic has the same error: check for N, n, No, no, to decide not to go out, then go out if they answer βtea and cookiesβ.
In addition, getAnswer accepts the answer and calls to chooseOptions (which in turn will receive some input to give getAnswer ): you are not looping: you are returning. And you do the same thing (get a response from the input) from two different places. What happens if I want to change std::cin with some other thread? Anything to change? How many different places?
Better logic should make the answer be consistent.
In your main program, you should do something like
bool do_exit = false; while(!do_exit) { //All useful stuff and then ... do_exit = getAnswer(std::cin, std::cout, "Do you want to exit? [yes/no]", "please answer yes or no"); }
Or, more briefly,
for(bool do_exit=false, !do_exit, do_exit=getAnswer( "Do you want to exit? [yes/no]", "please answer yes or no") ) { //usefull stuff here }
Now let's move on to the logic of the answer:
You should get one line of input (not one word: one line, since I can enter "yes, I want"), so cin>>string does not play well: std::get_line . If yes, return true, if no returns false and if something else repeats the read.
bool getAnswer(std::istream& istr, std::ostream& ostr, const std::string& prompt, const std::string& reprompt) { ostr << prompt << std::endl; for(;;) { std::string line; std::getline(istr,line); if(line == "yes" || line == "Yes" || line == "Y" || line == "y") return true; if(line == "no" || line == "No" || line == "N" || line == "n") return false; ostr << reprompt << std::end; } }
This forces you to accept the well-known yes or no options, but refuse anything else.
Going even further, we can grasp the idea that cin / cout may be other types of streams, and maybe no one "prints".
To avoid going into an infinite loop, we can introduce a restriction on the attempt and throw an exception if it is reached:
bool getAnswer(std::istream& istr, std::ostream& ostr, const std::string& prompt, const std::string& reprompt) { ostr << prompt << std::endl; for(int attempt=5; attempt>0; --attempt) { std::string line; std::getline(istr,line); if(line == "yes" || line == "Yes" || line == "Y" || line == "y") return true; if(line == "no" || line == "No" || line == "N" || line == "n") return false; if(attempt>1) ostr << reprompt << " ("<<attempt-1<<" attempts remaining)"<<std::endl; } throw std::domain_error("cannot get valid input"); }
and let the caller eventually catch and perform some other action or, ultimately, gracefully complete the job.
In addition, we can parameterize not only i / o and questions, but also answers, but this is too far.