2010-02-27 20 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); 

} 

Haciendo una tarea, este es mi primer programa para escribir con objetos así que tengan paciencia conmigo. Simplemente no puedo obtener la salida de este código para que salga bien. Necesito una forma de salir del ciclo, y lo que estoy usando simplemente no está funcionando. ¿Alguna sugerencia, consejos o consejos?¿Cómo puedo salir de mi ciclo do/while?

Respuesta

5

Intente comparar el paro con el cero.

stop == '0' 

También puede simplificar su código haciendo esto.

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! No me di cuenta cuando usaba un número decimal como un char, tenía que poner las comillas a su alrededor, es bueno saberlo, ¡muchas gracias, amigo! –

+2

@ blakejc70 Dado que stop es un char y con la sobrecarga del método C++, su llamada a cin.get se enruta a través de una lógica de manejo de entrada que devolverá un código de carácter. Así que pare == '0' == 48 (asumiendo el conjunto de caracteres ASCII). – David

2

En este escenario, la bomba de gas de un tiempo extra después de los usuario pulse '0'. Suponiendo que esto no sea deseado, tiene lo que se conoce como un "error de uno por uno". Puedes solucionar este problema (y eliminar la variable temporal) de reordenación de su función como sigue:

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(); 
    } 
} 

evitar el uso de una sentencia break, puede utilizar la siguiente construcción:

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(); 
    } 
} 

EDITAR (2011 Septiembre 27): @TonyK El mero hecho de que un idioma proporcione una función no significa que deba usarse. La declaración goto es un ejemplo clásico de esto.

De acuerdo, con un bucle tan simple, realmente no hay diferencia entre usar una función y la ruptura. Ambos son claros. Sin embargo, cuando se agregan funciones adicionales un mes (o años) más tarde, junto con condiciones adicionales para salir del ciclo, es muy fácil encontrar declaraciones if con lógica compleja dentro de un bucle que es tan grande, tiene una dificultad el tiempo encuentra su comienzo, y mucho menos los puntos de salida. Una de las maneras de luchar contra este tipo de código inflado es escribir funciones cortas, simples y enfocadas que tienen un buen nombre. Si haces esto, el código se documenta solo. Compare

while (true) 

frente

while (shouldDispenseGas()) 

Del mismo modo, comparar esto con el STL for_each algoritmo. Claro, std::for_each(v.begin(), v.end(), &foo); es un poco más corto que for (int i = 0; i < v.size(); ++i) { ...body of foo()... }. Pero la verdadera ventaja es que es más fácil ver cuál es la intención. En el for_each inmediatamente verá que hará algo una vez, y solo una vez, a cada elemento. En el ciclo for, no tienes idea. El contador de bucle i puede cambiarse en el bucle. Un break también puede estar oculto dentro. Al eludir esta declaración break e insertar la lógica en shouldDispenseGas, inmediatamente comprende las condiciones bajo las cuales el ciclo continuará y finalizará.

+0

Hola, gracias por tu ayuda. Me preguntaba cómo detener eso, y pensé en usar un descanso, pero mi libro de texto me dice que no es una buena práctica, aunque mi profesor nunca dijo eso. ¿Qué piensas sobre esto? –

+0

En general, trato de poner la lógica de "interrupción" en la comparación siendo por el momento o para la declaración. Sin embargo, a veces es más fácil usar un descanso.En este caso, donde es increíblemente claro lo que está pasando, no creo que haya un problema con el uso de break. Una vez dicho esto, ciertamente puede evitar usarlo mientras mantiene la legibilidad a costa de escribir una función separada (como se muestra en la respuesta editada). – JKD

+0

+1 La segunda versión con la función extra me da la calidez de los fuzzies. :-) –

Cuestiones relacionadas