En C++, comment gérez-vous les mauvaises entrées? Par exemple, si le programme demande un entier, lorsque vous tapez un caractère, il devrait être capable de faire quelque chose, puis de boucler pour répéter l'entrée, mais la boucle devient infinie lorsque vous entrez un caractère lorsqu'un entier est nécessaire et vice versa.
La raison pour laquelle le programme entre dans une boucle infinie est parce que le mauvais indicateur d'entrée de std::cin
Est défini en raison de l'échec de l'entrée. La chose à faire est d'effacer cet indicateur et de supprimer la mauvaise entrée du tampon d'entrée.
//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";
}
Voir la FAQ C++ pour cela, et d'autres exemples, y compris l'ajout d'un minimum et/ou d'un maximum dans la condition.
Une autre façon serait d'obtenir l'entrée sous forme de chaîne et de la convertir en un entier avec std::stoi
Ou une autre méthode qui permet de vérifier la conversion.
La réponse la plus votée couvre très bien la solution.
En plus de cette réponse, cela peut aider à visualiser un peu mieux ce qui se passe:
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;
}
Vider le texte du tampon dans une variable n'est pas particulièrement utile, mais cela aide à visualiser pourquoi cin.ignore()
est nécessaire.
J'ai également noté la modification de la variable d'entrée, car si vous utilisez une variable d'entrée dans votre condition pour une boucle while
, ou une instruction switch, elle peut se retrouver dans un blocage ou remplir une condition que vous n'étiez pas 't attend, ce qui peut être plus déroutant à déboguer.