while tiempo infinito for ejemplo ciclos ciclo bucle c++ while-loop int iostream infinite-loop

c++ - tiempo - atrapado en el bucle infinito mientras



ciclo infinito c# (3)

Podrías leer la entrada como una cadena, convertirla en un entero y validarla ...

#include <iostream> #include <string> using namespace std; int main() { int number = 0; string input; do { cout << "Enter a number: "; cin >> input; number = atoi(input.c_str()); // atoi returns 0 on error.. if (number != 0 || input.compare("0") == 0) // but maybe the user really entered "0". break; cout << endl; cout << "Invalid input; please re-enter./n"; } while (1); cout << "You entered " << number << endl; return 0; }

Ejemplo de ejecución del programa:

% ./foo Enter a number: abc Invalid input; please re-enter. Enter a number: 2 You entered 2 % ./foo Enter a number: 0 You entered 0

.. aunque esta probablemente no es la solución más elegante.

En C ++, para manejar entradas incorrectas (como cuando el programa solicita un número entero pero usted escribe un carácter) debería poder hacer algo y luego repetir un ciclo para repetir la entrada.

Mi ciclo itera infinitamente cuando ingresas un caracter cuando se necesita un entero y viceversa:

#include<iostream> int main() { while (cout << "Enter a number" && !(cin >> num)) { cin.sync(); cin.clear(); cout << "Invalid input; please re-enter./n"; } }

¿Qué debo hacer para que el programa vuelva a solicitar la nueva entrada?


Si cin >> num falla, la entrada no válida debe eliminarse de la transmisión. Sugiero usar ignore lugar de sync para lograr esto. El motivo es que la sync no garantiza la eliminación de la entrada restante en todas las implementaciones de la Biblioteca estándar.

#include <iostream> #include <limits> int main() { int num; while (cout << "Enter a number" && !(cin >> num)) { cin.clear(); // clear the error // Remove input up to a new line cin.ignore(std::numeric_limits<std::streamsize>::max(),''/n''); cout << "Invalid input; please re-enter./n"; } }

El ejemplo anterior usa std::numeric_limits<std::streamsize>::max() se usa para recuperar el número máximo de caracteres que el buffer de entrada puede contener. Esto permite que ignore() elimine tantos caracteres como sea posible hasta la nueva línea. Es idiomático C ++ y es preferible a usar números mágicos que probablemente oculten el problema que estás teniendo actualmente.

Esto funciona bien pero no maneja situaciones donde la entrada contiene caracteres adicionales después del número. Para lidiar con esas situaciones, el ciclo debe cambiarse un poco para manejar la validación adicional. Una opción es leer una línea entera desde cin , colocarla en std::stringstream , leer el número de eso y luego hacer una validación adicional. Sin embargo, hay un caso especial que podría necesitarse tener en cuenta: una línea donde los únicos caracteres después del número son espacios en blanco. Afortunadamente, la biblioteca estándar proporciona el modificador de flujo std::skipws que permite que la situación se maneje fácilmente. El siguiente ejemplo muestra cómo hacer esto sin mucho esfuerzo

#include <iostream> #include <sstream> int main() { int num; for(;;) { std::cout << "Enter a number: " << std::flush; std::string line; std::getline(std::cin, line); // Read a line from console std::stringstream text(line); // store in a string stream char ch = 0; if(!(text >> num).fail() && (text >> std::skipws >> ch).fail()) { break; } std::cout << "Invalid input; please re-enter./n"; } return 0; }

La expresión (text >> std::skipws >> ch).fail() omitirá todos los espacios en blanco que aparecen después del número y luego intentará leer un solo carácter. Si no hay caracteres disponibles, la lectura fallará indicando que el usuario ingresó solo un número y nada más. Si tratamos de hacer esto con cin , esperaríamos a que el usuario ingrese más texto, incluso si la entrada es válida.


Use cin.ignore() lugar de cin.sync() y vea por qué de esta respuesta

while (cout << "Enter a number" && !(cin >> num)) { cin.clear(); // clear error cin.ignore(100, ''/n''); // ignore characters until next ''/n'' (or at most 100 chars) cout << "Invalid input; please re-enter./n"; }

Más sobre cin.ignore

Tenga en cuenta que puede ampliar el alcance de la cantidad de caracteres ignorados, hasta el máximo

cin.ignore(std::numeric_limits<std::streamsize>::max(), ''/n'');