cin per un int che introduce un char provoca Loop che dovrebbe controllare l’input per diventare selvaggio

Questa è una funzione del mio gioco che chiederà input e cin in “iAuswahl”! Quindi il ciclo while è controllato se è uno dei valori che voglio 1-9 se non si triggers e si suppone richieda un nuovo input. Strega lo fa per int. Ma se inserisco un carattere come r, diventerà pazzo e continuerò a restituirmi il mio cout e saltare il cin! Le mie domande sono: perché lo fa e come lo interrompo?

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); } 

Quando si verifica un errore durante la lettura da uno stream, viene impostato un flag di errore e non è più ansible leggere finché non si cancellano i flag di errore. Ecco perché ottieni 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'); 

Inoltre, è sbagliato utilizzare i risultati dell’operazione di input se non si sa se la lettura è riuscita in primo luogo. Non puoi formulare ipotesi sul valore di iAuswahl . Questo è uno degli errori più spesso commessi da neofiti che utilizzano i flussi. Controllare sempre se l’operazione di input era ok. Questo è più facile usando operator>> nel contesto booleano:

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

E, mio ​​Dio, questa linea

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

può essere solo questo:

 while (iAuswahl < 1 || iAuswahl > 9) 

Un ciclo corretto potrebbe essere simile a questo:

 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'); } 

È necessario cancellare il flag di errore dopo aver letto il tipo sbagliato, altrimenti cin si rifiuterà di leggere qualsiasi cosa, poiché sarà nello stato non valido. Inoltre, devi ignorare quel personaggio che non è stato letto da cin , perché ti rimarrà bloccato per sempre perché cercherà sempre di leggere da quel personaggio.

 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; } 

Anche,

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

può essere scritto come

 if(iAuswahl < 1 || iAushwahl > 9) 

Non dimenticare di inizializzare iAushwahl a 0 , o ad un altro valore, perché se il tuo cin >> iAushwahl fallisce, leggerai la variabile non inizializzata.