while repetir programa mientras desea continuar como c++ validation infinite-loop cin

c++ - repetir - do while en c



Bucle infinito con cin cuando se escribe cadena mientras se espera un nĂºmero (3)

En el siguiente ciclo, si escribimos caracteres como la entrada cin lugar de los números que se esperan, entonces entra en un ciclo infinito. ¿Podría alguien explicarme por qué ocurre esto?

Cuando usamos cin , si la entrada no es un número, ¿hay formas de detectar esto para evitar los problemas antes mencionados?

unsigned long ul_x1, ul_x2; while (1) { cin >> ul_x1 >> ul_x2; cout << "ux_x1 is " << ul_x1 << endl << "ul_x2 is " << ul_x2 << endl; }


Bueno, siempre tendrá un bucle infinito, pero sé que lo que realmente quiere saber es por qué cin no sigue pidiendo información sobre cada iteración de bucle que causa que su bucle infinito freerun.

La razón es porque cin falla en la situación que describes y no leerá más entradas en esas variables. Al dar cin entrada incorrecta, cin entra en el estado de falla y deja de solicitar la línea de comando para la entrada haciendo que el bucle se ejecute libremente.

Para la validación simple, puede intentar usar cin para validar sus entradas comprobando si cin está en el estado de falla. Cuando ocurre una falla, borre el estado de falla y fuerce la transmisión para descartar la entrada incorrecta . Esto devuelve cin a la operación normal para que pueda solicitar más entrada.

if (cin.fail()) { cout << "ERROR -- You did not enter an integer"; // get rid of failure state cin.clear(); // From Eric''s answer (thanks Eric) // discard ''bad'' character(s) cin.ignore(std::numeric_limits<std::streamsize>::max(), ''/n''); }

Para una validación más sofisticada, es posible que desee leer primero una cadena y hacer comprobaciones más sofisticadas de la cadena para asegurarse de que coincida con lo que esperaba.


Tal vez, es porque,

  1. cin es una función de transmisión. Cuando se ingresa un valor no numérico en lugar de números, se ignora. Y se le solicita volver a ingresar.
  2. Incluso si dio entradas numéricas, se le solicitarán más entradas ya que está en un bucle infinito.

Puede resolver este problema de esta manera: 1. Cree una función para incluir una entrada de cadena. 2. Devuélvalo como numérico después de la conversión. Use strtod () para la conversión.

Espero que esto ayude :)


Atención

Por favor, preste atención a la siguiente solución. Todavía no está completo para borrar el error en su caso. ¡Aún obtendrás un ciclo infinito!

if (cin.fail()) { cout << "Please enter an integer"; cin.clear(); }

Solución completa

La razón es que necesita borrar el estado de flujo fallido, así como descartar los caracteres no procesados. De lo contrario, el personaje malo todavía está allí y todavía obtienes bucles infinitos. Simplemente puede std :: cin.ignore () para lograr esto. Por ejemplo,

if (cin.fail()) { cout << "Please enter an integer"; // clear error state cin.clear(); // discard ''bad'' character(s) cin.ignore(std::numeric_limits<std::streamsize>::max(), ''/n''); }

Otra solución

También puede usar getline y stringstream para lograrlo. Aquí hay un breve ejemplo.

string input; while (1) { getline(cin, input); stringstream(input) >> x; cout << x << endl; }