Déterminer si une chaîne C est un int valide en C

Je dois vérifier si une chaîne C est un entier valide.

J’ai essayé les deux

int num=atoi(str); 

et

 int res=sscanf(str, "%d", &num); 

Mais l’envoi de la chaîne "8 -9 10" dans les deux lignes renvoyait simplement 8, sans indiquer l’invalidité de cette chaîne.

Quelqu’un peut-il suggérer une alternative?

Regardez strtol (), il peut vous renseigner sur les parties non valides de la chaîne par retour de pointeur.

Et méfiez-vous des exemples de code enthousiastes. Consultez la page de manuel pour une gestion complète des erreurs.

Je vais peut-être me faire strtol de ne pas utiliser strtol ou des fonctions similaires de la libc , mais raisonner à propos de ce problème n’est pas si difficile:

 #include  // if using C99... for C++ leave this out. #include  bool is_valid_int(const char *str) { // Handle negative numbers. // if (*str == '-') ++str; // Handle empty ssortingng or just "-". // if (!*str) return false; // Check for non-digit chars in the rest of the stirng. // while (*str) { if (!isdigit(*str)) return false; else ++str; } return true; } 

[NB: J’aurais peut-être fait isdigit(*str++) place du else pour le raccourcir, mais je me souviens que les normes disent qu’il est possible que isdigit soit une macro.]

J’imagine qu’une des limites est que cela ne retourne pas false si le nombre dans la chaîne ne tient pas dans un entier. Cela peut ou peut ne pas avoir d’importance pour vous.

Un moyen simple de le faire consisterait à lire le int et à vous assurer que la représentation de la chaîne est identique à la chaîne en entrée, en combinant par exemple atoi et itoa :

 int is_int(char const* p) { return strcmp(itoa(atoi(p)), p) == 0; } 

Pour vérifier si la chaîne contient un nombre valide, vous pouvez utiliser une expression régulière. Par exemple, pour les entiers, utilisez:

[- +]? [0-9] +

et un cas général pour les nombres à virgule flottante:

[+ -]? [0-9] + [.]? [0-9] * ([eE] [- +]? [0-9] +)?

Dans le cas de C ++ 11, les fonctions d’expressions régulières sont disponibles dans la bibliothèque, par exemple “std :: regex_match (…..)” donne la correspondance exacte. Le code devrait ressembler à ceci:

 #include  ..... std::ssortingng strnumber("-1.234e+01"); float number; if(regex_match(strnumber,std::regex("[+-]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?")) number=std::stof(strnumber); else std::cout<<"error, string is not a valid number"; 

Désolé de creuser le sujet, mais par souci d’exhaustivité et parce que ce fil est la première correspondance lors d’une recherche google …

Il est possible d’utiliser quelque chose comme:

 ret = sscanf(ssortingng, "%d%n", &number, &idx); if (ret == 0 || ssortingng[idx] != '\0') /* handle the error */ 

La directive %n , qui semble être le standard C selon la page de manuel, compte le nombre de caractères traités.

[Modifier] sscanf ne semble pas fournir un moyen de détecter les débordements, la famille de fonctions strtoX devrait donc être préférée à mon humble avis.