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