2012-04-27 17 views
14

En C++, ¿cómo maneja las entradas incorrectas? Por ejemplo, si el programa solicita un número entero, cuando escriba un carácter debería poder hacer algo y luego repetir para hacer la entrada, pero el ciclo se vuelve infinito cuando ingresa un carácter cuando se necesita un número entero y viceversa.Cómo manejar una entrada de tipo de datos incorrecta

Respuesta

32

El motivo por el cual el programa entra en un bucle infinito es porque el indicador de entrada incorrecta de std::cin se establece debido a la falla de la entrada. Lo que hay que hacer es borrar esa bandera y descartar la entrada incorrecta del buffer de entrada.

//executes loop if the input fails (e.g., no characters were read) 
while (std::cout << "Enter a number" && !(std::cin >> num)) { 
    std::cin.clear(); //clear bad input flag 
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); //discard input 
    std::cout << "Invalid input; please re-enter.\n"; 
} 

Ver the C++ FAQ para este y otros ejemplos, incluyendo la adición de un mínimo y/o máximo en la condición.

Otra forma sería obtener la entrada como una cadena y convertirla a un número entero con std::stoi o algún otro método que permita verificar la conversión.

+1

he hecho algunas investigaciones antes de preguntar aquí. Vi que pusieron cin.ignore (1000, '\ n'); que hace esto? ¡También! (Cin >> num) devuelve un booleano? No sabía que – Zik

+0

gracias por el sitio – Zik

+1

@Marvin, 'cin.ignore (1000, '\ n')' ignora/descarta caracteres en el búfer de entrada hasta que 1000 hayan sido descartados, o que se haya encontrado una nueva línea, lo que sea que venga primero. Es una buena manera de deshacerse de una línea. Verá en el ejemplo del parashift, usan el tamaño máximo de una secuencia en lugar de 1000 para representar una línea de longitud máxima. Yo uso 'cin.sync()' porque al hacer esto, quiero estar en igualdad de condiciones con el usuario (no leer la próxima línea todavía), así que lo descarto todo. Finalmente, 'cin' tiene un' operator void * ', por lo que no puede convertirse en un bool. – chris

0

Pruebe la entrada para ver si es o no lo que espera su programa. Si no es así, advierta al usuario que la entrada que proporcionaron es inaceptable.

0

Puede verificarlo a través del valor ASCII si el valor de ascii es entre 65 t0 90 o 97 a 122 el carácter.

3

La respuesta más votado abarca la solución realmente bien.

Además de esa respuesta, esto puede ayudar a visualizar lo que está pasando un poco mejor:

int main() 

    int input = 1;//set to 1 for illustrative purposes 
    bool cinState = false; 
    string test = "\0"; 
    while(input != -1){//enter -1 to exit 
     cout << "Please input (a) character(s): ";//input a character here as a test 
     cin >> input; //attempting to input a character to an int variable will cause cin to fail 
     cout << "input: " << input << endl;//input has changed from 1 to 0 
     cinState = cin;//cin is in bad state, returns false 
     cout << "cinState: " << cinState << endl; 
     cin.clear();//bad state flag cleared 
     cinState = cin;//cin now returns true and will input to a variable 
     cout << "cinState: " << cinState << endl; 
     cout << "Please enter character(s): "; 
     cin >> test;//remaining text in buffer is dumped here. cin will not pause if there is any text left in the buffer. 
     cout << "test: " << test << endl; 
    } 
    return 0;  
} 

Dumping el texto en el búfer a una variable no es particularmente útil, sin embargo, ayuda a visualizar qué cin.ignore() es necesario.

Noté también el cambio en la variable de entrada porque si está utilizando una variable de entrada en su condición para un bucle while, o una declaración de interruptor puede entrar en un punto muerto, o puede cumplir una condición de que no t expecting, que puede ser más confuso de depurar.

Cuestiones relacionadas