Помимо очевидной инверсии между & & и || все ответы на вопросы, позвольте мне пойти немного дальше, чтобы сделать еще одну ошибку очевидной (на самом деле не ошибка, а слабость дизайна): вы спрашиваете «да или нет», что-нибудь примите, и если ответ выглядит «да», вы Выход. Все остальное играет как нет. Даже «одна чашка кофе».
И инвертирование всей логики имеет ту же ошибку: проверьте для N, n, No, no, чтобы решить не выходить, означает выход, если на «чай и печенье» отвечают.
Кроме того, getAnswer
принимает ответ и вызывает chooseOptions
(который, в свою очередь получит некоторые вход, чтобы дать getAnswer
): вы не зацикливание: вы recoursing. И вы делаете то же самое (получите ответ от ввода) из двух разных мест. Что произойдет, если я хочу изменить std::cin
с каким-то другим потоком? Все, что нужно изменить? Сколько разных мест?
Лучшая логика должна заставлять ответ быть последовательным.
В главной программе вы должны сделать, скорее всего, что-то вроде
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");
}
Или, более сжато,
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
}
Теперь, позволяет получить в ответ логики:
Вы должны получить одну строку ввода (не только одно слово: одна строка, так как я могу набрать «да, я хочу»), поэтому cin>>string
не играет хорошо: лучше std::get_line
. Если это «да», верните true, если «no» вернет false и если что-то еще повторит чтение.
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;
}
}
Это заставляет вас принять хорошо известные варианты «да или нет», но отказаться от чего-либо еще.
Идя еще дальше, мы можем уяснить мысль о том, что cin/cout может быть другим видом потоков, и может быть, никто не «печатает».
Чтобы избежать идти в бесконечном цикле, можно ввести ограничение попытки и выбросить исключение, если оно будет достигнут:
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");
}
и пусть вызывающие в конечном итоге поймать и сделать некоторые другие действия, или в конце концов, изящно прекращается.
Кроме того, мы можем параметризовать не только вопросы и ответы, но и ответы, но это слишком далеко.
Измените '||' на '&&'. – Maroun
why && теперь я действительно смущен. в то время как нет да или нет нет, тогда продолжайте цикл, если «да» или «нет», затем перерыв цикла – airsoftFreak
Я добавил объяснение в качестве ответа, так как он не соответствует комментариям. – Maroun