IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Besoin d'aide pour strtod


Sujet :

C

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Par défaut Besoin d'aide pour strtod
    Bonjour, j'essaie de valider la conversion d'une chaine char* en un double, mais j'ai de la difficulté avec le endptr que la fonction doit manipuler qui est supposé pointer après le dernier char converti.

    Car ma chaîne a convertir peut-être n'importe quoi et de n'importe quelle longueur, donc je dois gérer les débordement inférieur et supérieur et de plus vérifier qu'il a bien TOUT converti, car il converti quand même les trucs du genre: "wq232.5" ou bien "45 ewew"

    Mais comment je peux savoir que tout est bien converti ou si ce n'est pas bien converti ? Est-ce que quelqu'un pourrait me donner un exemple d'utilisation de strtod gérant ces erreurs svp ?

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 50
    Par défaut
    Il faudrais que tu montre ce que tu fais. J'ai essaye ca, qui marche il me semble :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%f\n", strtod(av[1], &av[strlen(av[1] - 1)]));

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
     
    int argumentEstValide(char* argument) {
     
       errno = 0; 
       char* ptrfin;
       double v;
       v = strtod(argument, &ptrfin);
       printf("v: %lf\n", v);
       printf("ptrfin: %d\n", ptrfin);
     
       if (errno == ERANGE)
        {
            if (v == 0)
                fprintf(stderr, "nombre trop proche de zéro\n");
            else if (v == HUGE_VAL)
                fprintf(stderr, "nombre trop grand\n");
            else
                fprintf(stderr, "nombre trop petit\n");
            exit(EXIT_FAILURE);
     
            return 0;
        }
        return 1;
     
    }
    J'ai remarqué que si la conversion échoue la fonction renvoie 0, mais comment je peux savoir si il y a eu une erreur ou si c'est parce que ma chaine contenait quelque chose qui amenait a une valeur de zéro ?

    Aussi, si la conversion réussi mais encore là la valeur peut être de zéro, comment savoir si elle a converti complètement ma chaîne ?

  4. #4
    Membre émérite Avatar de stephl
    Profil pro
    Développeur informatique
    Inscrit en
    Février 2007
    Messages
    643
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Février 2007
    Messages : 643
    Par défaut
    Pour le problème des caractères non numériques, je pense qu'il faut tester si *ptrfin==0. Si oui, alors OK; sinon, il y a une erreur.

  5. #5
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par AsmCode
    J'ai remarqué que si la conversion échoue la fonction renvoie 0, mais comment je peux savoir si il y a eu une erreur ou si c'est parce que ma chaine contenait quelque chose qui amenait a une valeur de zéro ?
    En lisant la doc... http://man.developpez.com/man3/strtod.3.php

    Citation Envoyé par doc de strtod
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    #include <stdlib.h>
    double strtod (const char *nptr, char **endptr);
    <...>
    Si aucune conversion n'est possible, la fonction renvoie zéro, et la valeur de nptr est stockée dans endptr.
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  6. #6
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    In Documenta Veritas (du latin de cuisine)

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Par défaut
    C'est ce que j'ai lu, mais en vérifiant si le pointeur de fin est NULL on sait si la conversion a réussi ou échoué, d'après mes tests en tout cas.

    Mais pour le débordement ça ne fonctionne pas, si ça déborde le programme se termine brusquement. Que faire pour cela ?

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par AsmCode
    C'est ce que j'ai lu, mais en vérifiant si le pointeur de fin est NULL on sait si la conversion a réussi ou échoué, d'après mes tests en tout cas.
    Non! Si la valeur passée en deuxième paramètre de strtod() n'est pas NULL, alors le pointeur de fin pointera sur le premier caractère invalide. Si la chaîne passée à ta fonction est "1.2345", le pointeur de fin pointera sur le caractère nul de fin de chaîne '\0'.

    Si un caractère invalide est remncontré, le pointeur de fin pointe sur ce caractère. Si aucune convertion n'est possible, le pointeur de fin prend la valeur du pointeur passé en 1er argument de strtod() et la fonction renvoie 0. Le pointeur de fin ne prend jamais la valeur NULL ici.

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  9. #9
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Ce code fonctionne...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    int argumentEstValide(const char *s_input)
    {
        int ret = 1;
        double d;
        char *p_end = NULL;
     
        d = strtod(s_input, &p_end);
        if (d == 0.0 && p_end == s_input)
        {
            fprintf(stderr, "Aucune convertion n'a eu lieu!\n");
            ret = 0;
        }
        else if (*p_end != '\0')
        {
            fprintf(stderr, "La chaîne contient des caractères invalides\n");
            ret = 0;
        }
        else if (errno == ERANGE)
        {
            if (d == 0)
            {
                fprintf(stderr, "nombre trop proche de zéro\n");
            }
            else if (d == HUGE_VAL)
            {
                fprintf(stderr, "nombre trop grand\n");
            }
            else
            {
                fprintf(stderr, "nombre trop petit\n");
            }
            ret = 0;
        }
        return ret;
    }
    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Par défaut
    Citation Envoyé par mujigka
    Non! Si la valeur passée en deuxième paramètre de strtod() n'est pas NULL, alors le pointeur de fin pointera sur le premier caractère invalide. Si la chaîne passée à ta fonction est "1.2345", le pointeur de fin pointera sur le caractère nul de fin de chaîne '\0'.

    Si un caractère invalide est remncontré, le pointeur de fin pointe sur ce caractère. Si aucune convertion n'est possible, le pointeur de fin prend la valeur du pointeur passé en 1er argument de strtod() et la fonction renvoie 0. Le pointeur de fin ne prend jamais la valeur NULL ici.

    Thierry
    C'est ce que je dis donc si c'est null cela veut dire que tout s'est bien passé, car si il rencontre un caractère invalide il ne sera pas null, si il n'a pas réussi a convertir il ne sera pas null, donc NULL == conversion réussi. Non ?

    Car moi dans mon cas la chaine n'est jamais vide donc le pointeur jamais null, ensuite je ne veux pas savoir si ça n'a pas converti ou si ça a converti une partie seulement. Ce que j'ai besoin de savoir c'est si c'est converti complètement, ou non

  11. #11
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par AsmCode
    C'est ce que je dis donc si c'est null cela veut dire que tout s'est bien passé, car si il rencontre un caractère invalide il ne sera pas null, si il n'a pas réussi a convertir il ne sera pas null, donc NULL == conversion réussi. Non ?
    Il faut cesser de confondre NUL ou nul ou null ou 0 ou '\0' qui est le caractère de fin de chaine avec NULL qui est la constante signifiant 'pointeur invalide'.

    Si le pointeur pend ou endptr, peu importe son nom (2ème paramètre de strtod()), pointe sur 0, c'est que la conversion a réussie. Si il pointe sur autre chose que 0, c'est que la conversion n'est pas garantie (caractères non attendus dans la chaine à convertir). Si il vaut NULL c'est qu'il y a un bug grave parce que c'est en principe impossible à ma connaissance (qui n'est pas infinie).

  12. #12
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par AsmCode
    donc NULL == conversion réussi. Non ?
    Non!
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  13. #13
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    309
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 309
    Par défaut
    Ok, mais quoi qu'il en soit, si j'entres un nombre trop grand comme: 9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999

    Le programme plante au lieu d'afficher le message que c'est un nombre trop grand.

  14. #14
    Membre Expert
    Homme Profil pro
    Dév. Java & C#
    Inscrit en
    Octobre 2002
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dév. Java & C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2002
    Messages : 1 414
    Par défaut
    A mon avis, tu as un autre problème. Probablement un problème de mémoire:

    Voici un code pour tester la fonction argumentEstValide:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <errno.h> 
    #include <math.h>
     
    static int argumentEstValide(const char *s_input) {
        int ret = 1;
        double d;
        char *p_end = NULL;
     
        d = strtod(s_input, &p_end);
        if (d == 0.0 && p_end == s_input) {
            fprintf(stderr, "Aucune convertion n'a eu lieu!\n");
            ret = 0;
        }
        else if (*p_end != '\0') {
            fprintf(stderr, "La chaîne contient des caractères invalides\n");
            ret = 0;
        }
        else if (errno == ERANGE) {
            if (d == 0) {
                fprintf(stderr, "nombre trop proche de zéro\n");
            }
            else if (d == HUGE_VAL) {
                fprintf(stderr, "nombre trop grand\n");
            }
            else {
                fprintf(stderr, "nombre trop petit\n");
            }
            ret = 0;
        }
        return ret;
    }
     
    int main(int argc, char* args[]) {
        int status = EXIT_SUCCESS;
     
        if (1 < argc) {
            argumentEstValide(args[1]);
        }
        else {
            puts("USAGE: str2d <nombre à virgule à valider>\n");
            status = EXIT_FAILURE;
        }
        return status;
    }
    Et il fonctionnne même pour des chaînes de caractères très longues...

  15. #15
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par AsmCode
    Ok, mais quoi qu'il en soit, si j'entres un nombre trop grand comme: 99999999999999999999999999<...>

    Le programme plante au lieu d'afficher le message que c'est un nombre trop grand.
    Problème en amont au niveau de la saisie.

    Montre ton code.

  16. #16
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par AsmCode
    Ok, mais quoi qu'il en soit, si j'entres un nombre trop grand comme: 99999999999999999999999999999999999999999999999999<...>
    Le programme plante au lieu d'afficher le message que c'est un nombre trop grand.
    J'ai testé la fonction argumentEstValide() avant de soumettre et ça fonctionne... Peux-tu poster le code avec lequel tu as testé la fonction?

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

Discussions similaires

  1. besoin d'aide pour une requête
    Par Damien69 dans le forum Langage SQL
    Réponses: 11
    Dernier message: 31/03/2004, 16h38
  2. besoin d'aide pour le composant DBComboBox
    Par jane2002 dans le forum Bases de données
    Réponses: 8
    Dernier message: 28/02/2004, 20h01
  3. [Kylix] besoin d'aide pour installer kylix3
    Par Sph@x dans le forum EDI
    Réponses: 3
    Dernier message: 11/02/2004, 14h53
  4. [TP]besoin d'aide pour commandes inconnues
    Par Upal dans le forum Turbo Pascal
    Réponses: 15
    Dernier message: 03/10/2002, 11h48
  5. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 18h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo