web-dev-qa-db-fra.com

Vérifier si l'entrée est un nombre ou une chaîne en C++

J'ai écrit le code suivant pour vérifier si l'entrée (answer3) est un nombre ou une chaîne. Si ce n'est pas un nombre, il doit renvoyer "Entrer des numéros uniquement", mais le résultat est identique, même pour les nombres. Veuillez me suggérer une solution.

#include <iostream>
#include <string>
#include <typeinfo>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

using namespace std; 
int main ()
{

string ques1= "Client's Name :";
string ques2 = "Client's Address :";
string ques3 = "Mobile Number :";

char answer1 [80];
string answer2;
int answer3;

     cout<<ques1<<endl;    
     cin>>answer1;      

     cout<<ques2<<endl;    
     cin>>answer2; 

     cout<<ques3<<endl;
     cin>>answer3;

       if (isdigit(answer3))
       {
              cout<<"Correct"<<endl;     

              }

        else
        {
          cout<<"Enter Numbers Only"<<endl;  

            }

 system("pause>null");
 return 0;  

}
6
WESTRUK

Si vous utilisez C++ 98 , vous pouvez utiliser stringstreams (#include <sstream>):

std::string s = "1234798797";
std::istringstream iss(s);

int num = 0;

if (!(iss >> num).fail()) {
    std::cout << num << std::endl;
}
else {
    std::cerr << "There was a problem converting the string to an integer!" << std::endl;
}

Si le boost est disponible , vous pouvez utiliser lexical_cast (#include <boost/lexical_cast.hpp>):

std::string s = "1234798797";
int num = boost::lexical_cast<int>(si);//num is 1234798797
std::cout << num << std::endl;

Si C++ 11 est disponible , vous pouvez utiliser la fonction std::stoiintégrée à partir de <string>:

std::string s = "1234798797";
int mynum = std::stoi(s);
std::cout << mynum << std::endl;

LES SORTIES:

1234798797
7
jrd1

Vous pouvez utiliser regex pour faire ceci:

#include <regex>

bool isNumber(std::string x){
    std::regex e ("^-?\\d+");
    if (std::regex_match (x,e)) return true;
    else return false;}

Si vous voulez faire de isNumber() une fonction générique pouvant prendre n'importe quel type d'entrée:

#include <regex>
#include <sstream>

template<typename T>
bool isNumber(T x){
    std::string s;
    std::regex e ("^-?\\d+");
    std::stringstream ss; 
    ss << x;
    ss >>s;
    if (std::regex_match (s,e)) return true;
    else return false;}

La fonction isNumber() ci-dessus vérifie que seule la valeur entière, double ou float (qui contient le point .) ne renvoie pas la valeur true. Si vous souhaitez également une précision, modifiez la ligne regex en:

std::regex e ("^-?\\d*\\.?\\d+");

Si vous voulez une solution plus efficace, voyez celui-ci .

6
Jahid

La fonction isdigit () est utilisée pour tester uniquement les chiffres (0,1, ..., 9)

utiliser cette fonction pour vérifier les nombres

bool is_number(const std::string& s)
{
    std::string::const_iterator it = s.begin();
    while (it != s.end() && std::isdigit(*it)) ++it;
    return !s.empty() && it == s.end();
}
2
Chethan N

Une autre réponse en utilisant strtod :

bool isNumber(const std::string& s){
   if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
   char * p ;
   strtod(s.c_str(), &p) ;
   return (*p == 0) ;
}

Pour pouvoir gérer n'importe quel type de paramètre, utilisez un modèle:

#include <sstream>

template<typename T>
bool isNumber(T x){
   std::string s;
   std::stringstream ss; 
   ss << x;
   ss >>s;
   if(s.empty() || std::isspace(s[0]) || std::isalpha(s[0])) return false ;
   char * p ;
   strtod(s.c_str(), &p) ;
   return (*p == 0) ;
}

Note:

  1. Un espace blanc le fera retourner faux.
  2. NAN et INF le feront retourner faux (pour être exact, tout caractère sauf exposant valide le rendra faux). Si vous souhaitez autoriser nan et inf, supprimez la partie || std::isalpha(s[0]).
  3. la forme scientifique est autorisée iee + 12e retournera vrai.
  4. Double/float ou integer retournera true.
  5. Ceci est plus efficace que le regex answer . (regex est lourd).
1
Jahid

L'entrée de isdigit est une valeur entière. Cependant, il ne retournera true (non nul) que si la valeur correspond à '0' - '9'. Si vous les convertissez en valeurs entières, elles sont comprises entre 48 et 57. Pour toutes les autres valeurs, isdigit renverra false (zéro).

Vous pouvez vérifier si vous avez un entier en modifiant la logique de vérification:

if ( cin.fail() )
{
   cout<<"Correct"<<endl;     
}
else
{
   cout<<"Enter Numbers Only"<<endl;  
}
1
R Sahu

C'est une question un peu ancienne, mais je me suis dit que j'ajouterais ma propre solution que j'utilise dans mon code.

Une autre façon de vérifier si une chaîne est un nombre est la fonction std::stod, qui a été mentionnée, mais je l'utilise un peu différemment. Dans mon cas d'utilisation, j'utilise un bloc try-catch pour vérifier si l'entrée est une chaîne ou un nombre, comme avec votre code:

...
try {
    double n = stod(answer3);
    //This will only be reached if the number was converted properly.
    cout << "Correct" << endl;
} catch (invalid_argument &ex) {
    cout << "Enter Numbers Only" << endl;
}
...

Le principal problème de cette solution est que les chaînes qui commencent par des nombres (mais ne sont pas tous des nombres) seront seront converties en nombres. Cela peut être facilement corrigé en utilisant std::to_string sur le nombre renvoyé et en le comparant à la chaîne d'origine.

0
MarkSill

Le phénomène d’intérêt est que isdigit requiert char pour être converti en unsigned char. (Voir aussi ici ).

0
user3277268