Comment valider une entrée numérique C ++

J’aimerais savoir comment limiter une valeur d’entrée aux décimales signées à l’aide de std::cin .

Si la variable de sauvegarde de cin est un nombre et que la chaîne fournie n’est pas un nombre, la valeur de retour est false, vous avez donc besoin d’une boucle:

 int someVal; while(!(cin >> someVal)) { cin.reset(); cout << "Invalid value, try again."; } 
 double i; //Reading the value cin >> i; //Numeric input validation if(!cin.eof()) { peeked = cin.peek(); if(peeked == 10 && cin.good()) { //Good! count << "i is a decimal"; } else { count << "i is not a decimal"; cin.clear(); cin >> discard; } } 

Cela donne aussi un message d’erreur avec l’entrée -1a2.0 évitant l’atsortingbution de seulement -1 à i.

L’opérateur >> de cin fonctionne en lisant un caractère à la fois jusqu’à ce qu’il apparaisse en blanc. Cela va slurp la chaîne entière -1a2.0 , ce qui n’est évidemment pas un nombre, donc l’opération échoue. Il semble que vous ayez en fait trois champs, -1, a et 2.0. Si vous séparez les données par des espaces, cin sera en mesure de les lire sans problème. Rappelez-vous juste de lire un caractère pour le deuxième champ.

En combinant les techniques de la meilleure réponse ici et de ce site, je reçois

input.h

 #include  // Provides ios_base::failure #include  // Provides cin template  T getValidatedInput() { // Get input of type T T result; cin >> result; // Check if the failbit has been set, meaning the beginning of the input // was not type T. Also make sure the result is the only thing in the input // stream, otherwise things like 2b would be a valid int. if (cin.fail() || cin.get() != '\n') { // Set the error state flag back to goodbit. If you need to get the input // again (eg this is in a while loop), this is essential. Otherwise, the // failbit will stay set. cin.clear(); // Clear the input stream using and empty while loop. while (cin.get() != '\n') ; // Throw an exception. Allows the caller to handle it any way you see fit // (exit, ask for input again, etc.) throw ios_base::failure("Invalid input."); } return result; } 

Usage

inputtest.cpp

 #include  // Provides EXIT_SUCCESS #include  // Provides cout, cerr, endl #include "input.h" // Provides getValidatedInput() int main() { using namespace std; int input; while (true) { cout << "Enter an integer: "; try { input = getValidatedInput(); } catch (exception e) { cerr << e.what() << endl; continue; } break; } cout << "You entered: " << input << endl; return EXIT_SUCCESS; } 

Échantillon échantillon

Entrez un entier: a
Entrée invalide.
Entrez un entier: 2b
Entrée invalide.
Entrez un entier: 3
Vous avez entré: 3.

Je n’essaie pas d’être impoli. Je voulais simplement partager une solution que j’ai fournie et qui, à mon avis, est plus robuste et permet une meilleure validation des entrées.

Veuillez vous référer à: Ma solution pour la validation d’entrée

J’ai essayé de nombreuses techniques pour lire les entrées entières de l’utilisateur à l’aide de l’opérateur >> , mais d’une manière ou d’une autre, toutes mes expériences ont échoué.

Maintenant, je pense que la fonction getline() (pas la méthode portant le même nom sur std::istream ) et la fonction strtol() de include cstdlib est la seule solution cohérente prévisible pour ce problème. J’apprécierais si quelqu’un me prouvait le contraire. Voici quelque chose comme celui que j’utilise:

 #include  #include  // @arg prompt The question to ask. Will be used again on failure. int GetInt(const char* prompt = "? ") { using namespace std; // *1 while(true) { cout << prompt; string s; getline(cin,s); char *endp = 0; int ret = strtol(s.c_str(),&endp,10); if(endp!=s.c_str() && !*endp) return ret; } } 
  • * 1: Placement en using namespace whatever; à la scope mondiale peut conduire à brisé "unités" (google!) sur des projets plus importants, donc devrait être évité. Pratique pour ne pas utiliser de cette façon, même sur des projets plus petits!
  • Lire des entiers à partir de fichiers est une question très différente. L'approche de Raúl Roa peut être bonne pour cela si elle est correctement élaborée. Je suggère également que les mauvais fichiers d’entrée ne soient pas tolérés, mais cela dépend vraiment de l’application.
  • Soyez averti que l'utilisation de >> et getline() dans le même programme sur cin entraînera des problèmes. Utilisez-en un seul ou google pour savoir comment gérer le problème (pas trop difficile).

Quelque chose comme:

 double a; cin >> a; 

Devrait lire votre amende signée “décimale”.

Vous aurez besoin d’une boucle et de code pour vous assurer qu’elle gère les entrées non valides de manière judicieuse.

Bonne chance!