Oprócz ewidentnej inwersji pomiędzy & & i || wszystkie odpowiedzi mówią, pozwól mi pójść trochę dalej, aby pokazać inny błąd (nie tak naprawdę błąd, ale słabość projektu): pytasz "tak lub nie" akceptujesz cokolwiek, a jeśli odpowiedź wygląda "tak", ty wyjście. Coś jeszcze gra jak nie. Nawet "jedna filiżanka kawy".
Odwracanie całej logiki ma tę samą wadę: sprawdź dla N, n, Nie, nie, aby zdecydować, że nie wyjdziesz oznacza wyjście, jeśli "herbata i herbatniki" są odbierane.
Również getAnswer
trwa odpowiedzieć i wzywa chooseOptions
(który z kolei dostanie jakiś wejście dać getAnswer
): nie jesteś zapętlenie: jesteś recoursing. I robisz to samo (otrzymujesz odpowiedź z danych wejściowych) z dwóch różnych miejsc. Co się stanie, jeśli chcę zmienić std::cin
z innym strumieniem? Wszystko do zmiany? W ilu różnych miejscach?
Znacznie lepsza logika powinna wymusić spójność odpowiedzi.
W swoim głównym programie należy zrobić najprawdopodobniej coś
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");
}
Albo, bardziej zwięźle,
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
}
Teraz przejdźmy do logiki odpowiedź:
trzeba uzyskać jedną linię wejścia (nie tylko jedno słowo: jedna linia, ponieważ mogę wpisać "tak, chcę"), więc cin>>string
nie gra dobrze: lepiej std::get_line
. Jeśli "tak" zwróci true, jeśli "nie" zwróci false i jeśli cokolwiek innego powtórzy odczyt.
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;
}
}
To sprawia, że akceptujesz dobrze znane warianty "tak lub nie", ale odmawiasz niczego innego.
Idąc dalej, możemy sobie wyobrazić, że cin/cout może być innym rodzajem strumienia, i może być, że nie ma nikogo "piszącego".
Aby uniknąć iść w nieskończonej pętli, możemy wprowadzić limit próba i wyjątek, jeśli zostanie osiągnięty:
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");
}
i niech rozmówca, aby w końcu złapać i zrobić kilka innych działań, lub ostatecznie z gracją zakończyć.
Co więcej, możemy parametryzować nie tylko i/o i pytania, ale także odpowiedzi, ale jest to zbyt daleko.
Zmień '||' na '&&'. – Maroun
dlaczego && teraz jestem naprawdę zdezorientowany. podczas gdy nie tak lub nie nie, kontynuuj pętlę, jeśli "tak" lub "nie" przerwij pętlę – airsoftFreak
Dodałem wyjaśnienie jako odpowiedź, ponieważ nie pasuje do komentarza. – Maroun