J'ai eu un peu de mal à essayer d'écrire une fonction qui vérifie si une chaîne est un nombre. Pour un jeu que j'écris, j'ai juste besoin de vérifier si une ligne du fichier que je lis est un nombre ou non (je saurai si c'est un paramètre de cette façon). J'ai écrit la fonction ci-dessous qui, je pense, fonctionnait correctement (ou j'ai accidentellement modifié pour l'arrêter ou je suis schizophrène ou Windows est schizophrène):
bool isParam (string line)
{
if (isdigit(atoi(line.c_str())))
return true;
return false;
}
c++
visual-c++
Brendan Weinstein
la source
la source
if (expr) return true; return false;
! Écrivez justereturn expr;
.if (expr) return expr; else return expr;
,if (expr == true)
,(if expr != false)
, ouif ((expr == true) == true)
. Ils introduisent tous une complexité qui ne profite pas à l'écrivain, au lecteur ou au compilateur du code. L'élimination de la complexité inutile n'est pas un raccourci; c'est la clé pour écrire de meilleurs logiciels.Réponses:
Le moyen le plus efficace serait simplement de parcourir la chaîne jusqu'à ce que vous trouviez un caractère non numérique. S'il y a des caractères non numériques, vous pouvez considérer la chaîne comme un nombre.
Ou si vous voulez le faire de la manière C ++ 11:
Comme indiqué dans les commentaires ci-dessous, cela ne fonctionne que pour les entiers positifs. Si vous avez besoin de détecter des entiers ou des fractions négatifs, vous devriez opter pour une solution basée sur une bibliothèque plus robuste. Cependant, l'ajout de la prise en charge des entiers négatifs est assez trivial.
la source
!s.empty() && s.find_first_not_of("0123456789") == std::string::npos;
pour un one-liner C ++ 03.int
. Il s'agit simplement d'identifier si une chaîne est composée de chiffres numériques. La longueur de la chaîne n'a pas d'importance.<string>
<algorithm>
et<cctype>
de faire fonctionner l'exemple C ++ 11.Pourquoi réinventer la roue? La bibliothèque standard C (également disponible en C ++) a une fonction qui fait exactement cela:
Si vous souhaitez gérer les fractions ou la notation scientifique, utilisez
strtod
plutôt (vous obtiendrez undouble
résultat).Si vous souhaitez autoriser les constantes hexadécimales et octales dans le style C / C ++ (
"0xABC"
), définissez le dernier paramètre à la0
place.Votre fonction peut alors être écrite comme
la source
atoi
tel qu'utilisé dans la question le fait également).p
sera réglé surnullptr
sistrtol
c'est réussi, non? Ce n'est pas ce que je vois :(p
pointera vers le NUL qui termine la chaîne. Alorsp != 0
et*p == 0
.Avec le compilateur C ++ 11, pour les entiers non négatifs, j'utiliserais quelque chose comme ça (notez le
::
au lieu destd::
):http://ideone.com/OjVJWh
la source
Vous pouvez le faire de la manière C ++ avec boost :: lexical_cast. Si vous insistez vraiment pour ne pas utiliser boost, vous pouvez simplement examiner ce qu'il fait et le faire. C'est assez simple.
la source
try{} catch{}
une bonne idée? Ne devrait-on pas l'éviter autant que possible?Je voulais juste ajouter cette idée qui utilise l'itération, mais un autre code fait cette itération:
Ce n'est pas robuste comme il se doit lors de la vérification d'un point décimal ou d'un signe moins car il permet qu'il y en ait plus d'un de chaque et à n'importe quel endroit. La bonne chose est qu'il s'agit d'une seule ligne de code et ne nécessite pas de bibliothèque tierce.
Retirez le "." et '-' si seuls les entiers positifs sont autorisés.
la source
std::string
, utilisez safind_first_not_of
fonction membre.Je suggérerais une approche regex. Une regex-match complète (par exemple, en utilisant boost :: regex ) avec
montrerait si la chaîne est un nombre ou non. Cela comprend les nombres positifs et négatifs, les nombres entiers et les nombres décimaux.
Autres variantes:
(seulement positif)
(seulement entier)
(seulement entier positif)
la source
std::regex
avec gcc 4.7, gcc 4.8 - ils lancent tous les deuxstd::regex_error
sur n'importe quel signe de l'[
expression rationnelle, même pour un innocent "[abc]" (est-ce que je fais ça mal?). clang-3.4 n'est pas du<regex>
tout au courant . Quoi qu'il en soit, cela semble être la réponse la plus saine, +1.Voici une autre façon de le faire en utilisant la
<regex>
bibliothèque:la source
Avec cette solution, vous pouvez tout vérifier, des nombres négatifs aux nombres positifs et même des nombres flottants. Lorsque vous modifiez le type de
num
en entier, vous obtiendrez une erreur si la chaîne contient un point.Prouver: programme C ++
la source
J'ai trouvé le code suivant le plus robuste (c ++ 11). Il attrape à la fois les entiers et les flottants.
la source
using namespace std;
soit inutile.Voici une solution pour vérifier les entiers positifs:
la source
Essaye ça:
la source
Brendan ceci
est presque ok.
en supposant que toute chaîne commençant par 0 est un nombre, ajoutez simplement une vérification pour ce cas
ofc "123hello" retournera vrai comme l'a noté Tony D.
la source
Le plus simple auquel je puisse penser en C ++
Exemple de code de travail: https://ideone.com/nRX51Y
la source
Ma solution utilisant C ++ 11 regex (
#include <regex>
), elle peut être utilisée pour une vérification plus précise, commeunsigned int
,double
etc.:Vous pouvez trouver ce code sur http://ideone.com/lyDtfi , il peut être facilement modifié pour répondre aux exigences.
la source
Une solution basée sur un commentaire de kbjorklu est:
Comme avec la réponse de David Rector, elle n'est pas robuste aux chaînes avec plusieurs points ou signes moins, mais vous pouvez supprimer ces caractères pour ne vérifier que les entiers.
Cependant, je suis partisan d'une solution, basée sur la solution de Ben Voigt , utilisant
strtod
dans cstdlib pour rechercher des valeurs décimales, la notation scientifique / technique, la notation hexidécimale (C ++ 11), ou même INF / INFINITY / NAN (C ++ 11) est:la source
Nous pouvons utiliser une classe stringstream .
la source
Utilisation
<regex>
. Ce code a été testé!la source
Après avoir consulté un peu plus la documentation, j'ai trouvé une réponse qui répond à mes besoins, mais qui ne sera probablement pas aussi utile pour les autres. Le voici (sans le retour ennuyeux true et return false déclarations :-))
la source
0
, vous obtiendrez un faux négatif.Je pense que cette expression régulière devrait gérer presque tous les cas
donc vous pouvez essayer la fonction suivante qui peut fonctionner avec les deux (Unicode et ANSI)
la source
Pour valider les doubles:
}
Pour valider les nombres entiers (avec négatifs)
}
Pour valider les entiers non signés
}
la source
comment cela fonctionne: la surcharge de stringstream >> peut convertir des chaînes en différents types arithmétiques, elle le fait en lisant les caractères séquentiellement à partir du stringstream (ss dans ce cas) jusqu'à ce qu'il manque de caractères OU le caractère suivant ne répond pas aux critères à stocker dans le type de variable de destination.
Exemple 1:
exemple2:
exemple3:
l'explication de la variable "garbage" ":
pourquoi ne pas simplement vérifier si l'extraction dans mon double a une valeur valide, puis retourner true si c'est le cas?
Remarquez que l'exemple3 ci-dessus lira toujours avec succès le numéro 11 dans la variable my_number même si la chaîne d'entrée est "11ABCD" (qui n'est pas un nombre).
pour gérer ce cas, nous pouvons faire une autre extraction dans une variable de chaîne (que j'ai nommée garbage) qui peut lire tout ce qui peut avoir été laissé dans le tampon de chaîne après l'extraction initiale dans la variable de type double. S'il reste quelque chose, il sera lu dans "garbage", ce qui signifie que la chaîne complète passée n'est pas un nombre (elle commence juste par un). dans ce cas, nous voudrions retourner false;
l'explication "0" préfixée:
tenter d'extraire un seul caractère dans un double échouera (renvoyer 0 dans notre double) mais déplacera toujours la position du tampon de chaîne après le caractère. Dans ce cas, notre lecture garbage sera vide, ce qui entraînerait le retour incorrect de la fonction true. pour contourner cela, j'ai ajouté un 0 à la chaîne de sorte que si, par exemple, la chaîne passée était "a", elle soit changée en "0a" afin que le 0 soit extrait dans le double et "a" soit extrait dans les ordures.
l'ajout d'un 0 n'affectera pas la valeur du nombre, donc le nombre sera toujours correctement extrait dans notre variable double.
la source
pour vérifier si une chaîne est un nombre entier ou une virgule flottante ou si vous pouvez utiliser:
la source
Encore une autre réponse, qui utilise
stold
(bien que vous puissiez également utiliserstof
/stod
si vous n'avez pas besoin de la précision).la source
Comme cela m'a été révélé dans une réponse à ma question connexe, je pense que vous devriez utiliser boost :: conversion :: try_lexical_convert
la source
Essaye ça:
la source
Vous pouvez tester si une chaîne est convertible en entier en utilisant boost :: lexical_cast . S'il lève une exception bad_lexical_cast, la chaîne ne peut pas être convertie, sinon elle le peut.
Voir l'exemple d'un tel programme de test ci-dessous:
Exemple d'exécution:
la source
Il y a quelques mois, j'ai implémenté un moyen de déterminer si une chaîne est un entier, un hexadécimal ou un double.
Ensuite, dans votre programme, vous pouvez facilement convertir le nombre en fonction de son type si vous procédez comme suit,
Vous pouvez réaliser que la fonction renverra un 0 si le nombre n'a pas été détecté. Le 0 il peut être traité comme faux (comme booléen).
la source
Je propose une convention simple:
Si la conversion en ASCII est> 0 ou si elle commence par 0, alors c'est un nombre. Ce n'est pas parfait mais rapide.
Quelque chose comme ça:
la source
Cette fonction prend en charge tous les cas possibles:
la source
Pourriez-vous simplement utiliser le code de retour de sscanf pour déterminer s'il s'agit d'un int?
la source