A parte l'inversione evidente tra & & e || tutte le risposte parlano, lasciami andare un po 'oltre, per rendere evidente un altro errore (non proprio un bug, ma una debolezza progettuale): chiedi "sì o no" accetta qualsiasi cosa e se la risposta sembra "si" tu Uscita. Qualcos'altro gioca come un no. Anche "una tazza di caffè".
E l'inversione di tutta la logica ha lo stesso errore: controllare per N, n, No, no per decidere di non uscire significa uscire se "tè e biscotti" hanno una risposta.
Inoltre, getAnswer
prende rispondere alle chiamate e chooseOptions
(che a sua volta ottenere qualche input per dare a getAnswer
): non stai Looping: sei recoursing. E stai facendo la stessa cosa (ottieni una risposta da un input) da due posti diversi. Cosa succede se voglio cambiare std::cin
con un altro flusso? Tutto da cambiare? In quanti posti diversi?
Una logica molto migliore dovrebbe forzare la risposta ad essere coerente.
Nel programma principale che si dovrebbe fare molto probabilmente qualcosa di simile
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");
}
O, più conciso,
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
}
Ora, consente di entrare nella logica risposta:
Devi ottieni una riga di input (non una sola parola: una riga, dato che posso digitare "sì, voglio"), quindi cin>>string
non gioca bene: meglio std::get_line
. Se è "sì", restituisce true, se "no" restituisce false e se non altro ripete la lettura.
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;
}
}
Questo consente di accettare le varianti "sì o no", ma rifiuta qualsiasi altra cosa.
Andando ancora oltre, possiamo rendere l'idea che cin/cout può essere un altro tipo di streaming e potrebbe non esserci nessuno che "digiti".
Per evitare di andare in un loop infinito, siamo in grado di introdurre un limite di tentativo e un'eccezione se si raggiunge:
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");
}
e lasciare che il chiamante per la cattura alla fine e fare qualche altra azione, o eventualmente terminare con grazia.
Inoltre, possiamo parametrizzare non solo l'I/O e le domande, ma anche le risposte, ma questo sta andando troppo lontano.
Cambia '||' in '&&'. – Maroun
why && now I'm really confused. mentre non si o no no, continua a ripetere il ciclo, se "si" o "no", quindi interrompi il ciclo – airsoftFreak
Ho aggiunto la spiegazione come risposta poiché non si adatta al commento. – Maroun