2010-02-27 11 views
6
void GasPump::dispense() 
{ 

     bool cont = true; 
     char stop; 

    do{ 
     cout << "Press any key, or enter to dispense.\n" 
      << "Or press 0 to stop: \n"; 
     cin.get(stop); 

     gasDispensed = gasDispensed + gasDispensedPerCycle; 
     charges = costPerGallon*gasDispensed; 
     displayGasNCharges(); 

     if(stop == 0) 
      cont = false; 

    } while(cont); 

} 

Fare un incarico, questo è il mio primo programma per scrivere con oggetti così da sopportare. Non riesco proprio a far uscire l'output di questo codice. Ho bisogno di un modo per uscire dal ciclo e quello che sto usando non funziona. Qualche suggerimento, suggerimento o suggerimento?Come posso interrompere il mio ciclo do/while?

risposta

5

Provare a confrontare lo stop con lo zero char.

stop == '0' 

Inoltre, è possibile semplificare il codice in questo modo.

void GasPump::dispense() 
{ 
    char stop; 

    do { 
     cout << "Press any key, or enter to dispense.\n" 
      << "Or press 0 to stop: \n"; 
     cin.get(stop); 

     gasDispensed = gasDispensed + gasDispensedPerCycle; 
     charges = costPerGallon*gasDispensed; 
     displayGasNCharges(); 
    } while (stop != '0'); 
} 
+0

Ooh! Non mi rendevo conto che quando si utilizzava un numero decimale come carattere si doveva mettere le virgolette intorno, buono a sapersi, grazie mille! –

+2

@ blakejc70 Poiché stop è un char e con il metodo C++ che esegue l'overloading, la chiamata a cin.get viene instradata a una logica di gestione dell'input che restituirà un codice di carattere. Quindi stop == '0' == 48 (andando per ipotesi di set di caratteri ASCII). – David

2

In questo scenario, si pompa un altro tempo dopo che l'utente ha premuto "0". Supponendo che ciò non sia desiderato, si dispone di ciò che è noto come "errore di errore singolo". È possibile risolvere questo (ed eliminare la variabile temporanea) riorganizzando la funzione come segue:

void GasPump::dispense() 
{ 
    while (true) { 
     cout << "Press any key, or enter to dispense.\n" 
      << "Or press 0 to stop: \n"; 

     if (cin.get() == '0') 
      break; 

     gasDispensed = gasDispensed + gasDispensedPerCycle; 
     charges = costPerGallon*gasDispensed; 
     displayGasNCharges(); 
    } 
} 

Per evitare di utilizzare un'istruzione break, è possibile utilizzare la seguente costruzione:

bool GasPump::shouldDispenseGas() 
{ 
    cout << "Press any key, or enter to dispense.\n" 
     << "Or press 0 to stop: \n"; 
    return (cin.get() != '0'); 
} 

void GasPump::dispense() 
{ 
    while (shouldDispenseGas()) { 
     gasDispensed = gasDispensed + gasDispensedPerCycle; 
     charges = costPerGallon*gasDispensed; 
     displayGasNCharges(); 
    } 
} 

EDIT (2011 Settembre 27): @TonyK Solo perché una lingua fornisce una funzionalità non significa che si dovrebbe usarla. L'istruzione goto è un classico esempio di questo.

Concesso, con un ciclo così semplice, non c'è davvero alcuna differenza tra l'utilizzo di una funzione e l'interruzione. Entrambi sono chiari. Tuttavia, quando le funzionalità extra vengono aggiunte un mese (o anni) più tardi, insieme a condizioni aggiuntive per rompere il loop, è molto facile trovare dichiarazioni if con una logica complessa all'interno di un ciclo così grande, si ha un duro tempo che trova il suo inizio, molto meno i punti di uscita. Uno dei modi per combattere questo tipo di codice è quello di scrivere funzioni brevi, semplici e focalizzate che siano ben definite. Se lo fai, il codice si documenta da solo. Confronta

while (true) 

contro

while (shouldDispenseGas()) 

Allo stesso modo, confronta al STL for_each algoritmo. Certo, std::for_each(v.begin(), v.end(), &foo); è un po 'più corto di for (int i = 0; i < v.size(); ++i) { ...body of foo()... }. Ma il vero vantaggio è che è più facile vedere quale sia l'intento. Nello for_each si vede subito che si farà qualcosa una volta sola, e solo una volta, a ciascun elemento. Nel ciclo for, non hai idea. Il contatore di loop i può essere modificato nel ciclo. A break potrebbe essere nascosto anche all'interno. Escludendo questa istruzione break e incorporando la logica in shouldDispenseGas, si capisce immediatamente le condizioni in base alle quali il ciclo continuerà e terminerà.

+0

Hey, grazie per il tuo aiuto. Mi stavo chiedendo come smetterlo, e ho pensato di usare una pausa, ma il mio libro di testo mi sta dicendo che non è una buona pratica, anche se il mio professore non l'ha mai detto. Qual è il tuo pensiero su questo? –

+0

In generale, provo a mettere la logica di "interruzione" nel confronto sia per il momento sia per l'istruzione. Tuttavia, a volte è solo più facile usare una pausa.In questo caso, dove è incredibilmente chiaro cosa sta succedendo, non penso che ci sia un problema con l'uso della pausa. Detto questo, è certamente possibile evitare di usarlo mantenendo la leggibilità al costo di scrivere una funzione separata (come mostrato nella risposta modificata). – JKD

+0

+1 La seconda versione con la funzione extra mi dà i fuzzies caldi. :-) –

Problemi correlati