cin para un int que ingresa un char provoca un bucle que se supone que verifica la entrada para volverse loco

¡Esta es una función de mi juego que pedirá entrada y cin en “iAuswahl”! Luego, el ciclo while comprueba si es uno de los valores que quiero 1-9 si no se activa y se supone que debe solicitar una nueva entrada. Bruja lo hace por int. Pero si ingreso un char como r se volverá loco y ¡simplemente sigan devolviéndome mi cout y omitiendo el cin! Mis preguntas son: ¿por qué lo hace y cómo lo detengo?

void zug(string sSpieler, int iDran){ int iAuswahl; char cXO = 'O'; if (iDran == 1) { cXO = 'X'; } cout << sSpieler << ", Sie sind am Zug. Bitte waehlen sie eins der Felder.\n" << endl; grafik(); cout <> " << cXO << " <<." <> iAuswahl; cout << endl; while ( iAuswahl != 1 && iAuswahl != 2 && iAuswahl != 3 && iAuswahl != 4 && iAuswahl != 5 && iAuswahl != 6 && iAuswahl != 7 && iAuswahl != 8 && iAuswahl != 9 ) { cout << "Kein gültiges Feld bitte wählen sie noch einmal!\n" <> iAuswahl; } feldfuellen(iAuswahl, cXO); } 

Cuando se produce un error al leer de un flujo, se establece un indicador de error y no es posible leer más hasta que borre los indicadores de error. Es por eso que obtienes un ciclo infinito.

 cin.clear(); // clears the error flags // this line discards all the input waiting in the stream cin.ignore(std::numeric_limits::max(), '\n'); 

Además, es incorrecto utilizar los resultados de la operación de entrada si no sabe si la lectura tuvo éxito en primer lugar. No puede hacer suposiciones sobre el valor de iAuswahl . Ese es uno de los errores más frecuentes cometidos por los novatos que usan transmisiones. Siempre verifique si la operación de entrada fue correcta. Esto se hace más fácilmente usando operator>> en contexto booleano:

 if (cin >> some_obj) { // evaluates to true if it succeeded } else { // something went wrong } 

Y, mi oh mi, esta línea

 while (iAuswahl != 1 && iAuswahl != 2 && iAuswahl != 3 && iAuswahl != 4 && iAuswahl != 5 && iAuswahl != 6 && iAuswahl != 7 && iAuswahl != 8 && iAuswahl != 9) 

puede ser solo esto:

 while (iAuswahl < 1 || iAuswahl > 9) 

Un bucle correcto podría verse más o menos así:

 while (true) { if ((cin >> iAuswahl) && (iAuswahl >= 1) && (iAuswahl <= 9)) break; std::cout << "error, try again\n"; cin.clear(); cin.ignore(std::numeric_limits::max(), '\n'); } 

Debe borrar el indicador de error después de leer el tipo incorrecto, de lo contrario, cin se negará a leer nada, ya que estará en el estado no válido. Además, debes ignorar ese personaje que no fue leído por cin , porque te atrapará en un ciclo para siempre porque siempre intentará leer de ese personaje.

 while (iAuswahl != 1 && iAuswahl != 2 && iAuswahl != 3 && iAuswahl != 4 && iAuswahl != 5 && iAuswahl != 6 && iAuswahl != 7 && iAuswahl != 8 && iAuswahl != 9) { cout << "Kein gültiges Feld bitte wählen sie noch einmal!\n" << endl; cin.clear(); // #include  cin.ignore(std::numeric_limits::max(), '\n'); cin >> iAuswahl; } 

También,

 while (iAuswahl != 1 && iAuswahl != 2 && iAuswahl != 3 && iAuswahl != 4 && iAuswahl != 5 && iAuswahl != 6 && iAuswahl != 7 && iAuswahl != 8 && iAuswahl != 9) 

Se puede escribir como

 if(iAuswahl < 1 || iAushwahl > 9) 

No te olvides de inicializar iAushwahl a 0 , o a algún otro valor, porque si tu cin >> iAushwahl falla, leerás la variable no inicializada.

Intereting Posts