Tester si une chaîne contient un nombre

Le
noone
Bonjour,

je souhaite tester si une chane (char *) contient un nombre.
Existe-t'il une fonction standard dans la libc pour a ?
J'ai vu int isdigit( int ch ) mais c'est juste pour tester si un char
est un chiffre
J'ai aussi vu int isdigit( int ch );
Une ide ?
Est-ce qu'utiliser une regexp en est une bonne ?

Merci d'avance
Vos réponses Page 3 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
scls19fr
Le #19252361
Ok merci à vous tous...
ça marche nickel
Marc
Le #19252501
Marc Espie wrote:

[strtol, avec ou sans const]
Accessoirement, ça répond à ma question pour le C++ : changer le
prototype serait certes bien, mais ça casserait la compatibilité avec le
C :-(



euh non, ca serait mal.

Il y a une vraie raison pour laquelle il n'y a pas de const, c'est que
tu ne sais pas si ton premier parametre est "vraiment" const ou pas, et
que le resultat doit y etre lie.

Je ne pense pas que tu puisses t'en sortir simplement mieux en C++...
Tu pourrais essayer d'avoir plusieurs surcharges de ta fonction, mais
j'ai l'impression que ca marchera aussi bien que d'essayer de surcharger
operator[] pour distinguer les acces en lecture des acces en ecriture
(e.g., tres mal sans rajouter plein d'objets intermediaires).



Tu crois ? La surcharge fonctionne bien, pour strstr et compagnie.

long int strtol(const char *nptr, const char **endptr, int base);
long int strtol(char *nptr, char **endptr, int base);

ça autorise toutes les variantes sauf strtol(const char*,char**,int) qui
est précisément celle qui fait des saletés. Malheureusement, on ne peut
pas écrire de code qui fonctionne à la fois avec le prototype du C et
avec celui que je propose : si le premier argument est const, le
prototype du C impose qu'il n'y ait pas de const, précisément la
construction que j'aurais voulu interdire :-(
Antoine Leca
Le #19253371
Le 02/05/2009 18:37, scls19fr
mais ce qui me gêne c'est que moi je veux faire une conversion vers un
int pas vers un long int !

et faire la conversion vers un long int juste pour détecter l'erreur
éventuelle puis faire un cast après vers un int
... ça me semble un peu discutable ... non ?



Tu vas rigoler.

Dans la bibliothèque standard, il y a bien une fonction qui fait ce que
veux: elle s'appelle sscanf(), et est super casse-gueule à utiliser
correctement même si elle est effectivement plus souple que strtol().
Pour le problème que tu as fini par exposer (mais en se limitant à des
valeurs en base 10), cela ressemble à
int derriere=0;
if( 1!=sscanf(source, "%d%n", &resultat, &derriere)
|| !derriere || source[derriere] ) c_est_pas_bon();

Seulement ce qui est drôle, c'est que la plupart du temps, sscanf"%d"
appelle strtol(,10) (ou un équivalent interne), et ensuite contraint le
résultat à rentrer dans un int... Autrement dit, il y a quand même une
conversion vers long ; qui plus est, dans la problématique de faire le
plus simple possible, une fonction à tirer-dans-les-coins comme sscanf()
n'est pas DU TOUT adaptée, car toute la souplesse que tu as grâce à la
chaîne de format etc. est compensée par une complexité de
l'implémentation, qui en embarqué signifie tout plein de code en trop et
surtout plein d'espace en pile nécessaire.


Si tu veux réellement gagner un poil à ce niveau, une solution serait de
prendre le code de la fonction strtol() (qui n'est pas compliqué) et de
le réecrire pour en faire Strtoi() qui se limiterait aux int. L'exercice
est intéressant en soi, car il va te montrer que le gain... est
extrêmement limité, peut-être 20 octets d'instruction ! (en comptant
comme gain les tests par rapport à INT_MIN et INT_MAX, mais en ne
comptant pas la taille des éventuelles primitives de calcul sur les
longs induites par strtol(), car dans la pratique elles seront presque
toujours présentes dans ton programme final).


Antoine
-ed-
Le #19262421
On 2 mai, 19:08, ""
je souhaite tester si une chaîne (char *) contient un nombre.



Faire la conversion en binaire avec strtol() ou strtod() et apprendre
à utiliser le 2 ème paramètre... Penser aussi à tester errno. Bien
lire la doc de ces fonctions.
-ed-
Le #19262411
On 2 mai, 20:37, scls19fr
Merci

mais ce qui me gêne c'est que moi je veux faire une conversion vers un
int pas vers un long int !



Pas de problèmes. Il suffit de tester la validité avant : >= INT_MIN
et <= INT_MAX.

et faire la conversion vers un long int juste pour détecter l'erreur
éventuelle puis faire un cast après vers un int
... ça me semble un peu discutable ... non ?



Pas besoin de cast, mais tu peux le mettre si ça calme le
compilateur..
-ed-
Le #19262401
On 3 mai, 08:19, scls19fr
Merci à vous tous... effectivement ma question était assez mal posé e
(mais c'était volontaire pour qu'elle soit suffisamment "ouverte")

Voilà ce que j'ai fait :

int contain_number(const char * token) {
  char ** endptr = NULL;
  long int val;
  val=strtol(token, endptr, 0);
  return !(val==0 && endptr==token);

}

mais ça ne fonctionne pas...

ça renvoie toujours vrai même avec une chaîne contenant du texte !



Il faut vraiment lire la doc...

#include #include #include
int contain_number (const char *token)
{
char *endptr = NULL;
long int val;
val = strtol (token, &endptr, 0);
return *endptr == 0 && errno != ERANGE;

}

#include
int main (void)
{
assert (contain_number ("0") == 1);
assert (contain_number ("10") == 1);
assert (contain_number ("a") == 0);
assert (contain_number ("10a") == 0);
assert (contain_number ("0x10a") == 1);

return 0;
}
Publicité
Poster une réponse
Anonyme