2012-03-22 22 views
5

Tengo un programa de este tipo:¿Por qué este programa entra en un bucle infinito?

#include <stdlib.h> 
#include <iostream> 

static int pswd=0; 

int main() { 

    do { 
     std::cout<<"I need your password:"<<std::endl;   
     std::cin>>pswd; 
    } while (pswd!=3855); 

    std::cout<<"Congratulations! Your password is correct! Your soul is free again!"<<std::endl; 
} 

Y tengo, puede haber, una pregunta estúpida. Cuando ingreso valores no válidos (con símbolos no numéricos o valores mayores que int) el programa entra en un bucle infinito sin leer ninguna información de la consola.

I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
I need your password: 
     ... 

¿Por qué este programa entra en un bucle sin fin?

Respuesta

10

Porque después de la entrada no válida, la transmisión está en estado fallido y todas las demás operaciones de entrada no son operativas. Siempre debe verificar el resultado de la operación de entrada.

do { 
    std::cout<<"I need your password:"<<std::endl;   
    if (!(std::cin >> pswd)) { 
     // clear error flags 
     std::cin.clear(); 
     // discard erroneous input (include <limits>) 
     std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); 
    } 
} while (pswd!=3855); 
+1

Esto tratará la entrada no numérica como una contraseña correcta. – interjay

+0

Quizás sería mejor absorber la entrada fallida en lugar de un 'break' –

+0

No presté realmente atención a la semántica del ciclo. Se trata principalmente de ilustrar el manejo de errores. –

1

que está tratando de leer un int pero puede echar un vistazo en el búfer de STDIN. Nota que no tiene un int, por lo que cin>> falla. (Ver fail bit).

Así que todo vuelve a dar vueltas. Debe verificar la conversión de tipo fallido.

1

Estoy bastante seguro de que quiere leer aquí una cadena, ya que no hay nada que controle lo que el usuario está escribiendo.

que desea leer en un char buffer (la de abajo soporta 256 caracteres) y luego se compara con la contraseña que está buscando usando strcmp:

#include <stdlib.h> 
#include <iostream.h> 

static int pswd=0; 
static char buffer[256]; 

int main() 
{ 
    do 
    { 
     std::cout<<"I need your password:"<<std::endl;   
     std::cin>>buffer; 
    } 
    while (strcmp("3855", buffer)); 
    std::cout<<"Congratulations! Your password is correct! Your soul is free again!"<<std::endl; 
} 

en cuenta que strcmp devuelve 0 cuando dos cuerdas partido.

+0

Gracias. Es una buena idea. Pero quiero entender este fenómeno únicamente con fines educativos. –

+1

Este es un potencial desbordamiento de búfer, use 'std :: string' en su lugar. Además, el encabezado para incluir es ''. – interjay

+0

¡Eso es verdad, por lo tanto, señalé que solo lee 256 caracteres! Pero sí, debería usar std :: string –