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 :

Créer fonctions pour saisir des nombres


Sujet :

C

  1. #1
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut Créer fonctions pour saisir des nombres
    Bonjour à tous,

    Je voudrais créer des fonctions permettant de saisir correctement au clavier des int, long et doubles. J'ai donc utilisé une fonction permettant de lire une chaîne de caractères au clavier que j'avais déjà créée, et converti cette chaîne grâce à atoi, atol ou atod.

    Mes fonctions :
    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
    /* lire_int : lit une chaine de caracteres et convertit en int */
     
    int lire_int(int *d)
    {
        int err;
        char temp[16] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            *d = atoi(temp);
        }
     
        return err;
    }
     
     
    /* lire_long : lit une chaine de caracteres et convertit en long */
     
    int lire_long(long *l)
    {
        int err;
        char temp[32] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            *l = atol(temp);
        }
     
        return err;
    }
     
     
    /* lire_double : lit une chaine de caracteres et convertit en double */
     
    int lire_double(double *lf)
    {
        int err;
        char temp[64] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            *lf = atof(temp);
        }
     
        return err;
    }
    Ainsi que ma fonction lire_ligne :
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    /* lire_ligne : lit une ligne sur l'entree standard et l'écrit
    dans un tableau de caractères */
     
    int lire_ligne(char* s, size_t t)
    {
        int c;
        int err;
        size_t i;
     
        /* le pointeur doit contenir une adresse */
     
        if (s != NULL)
        {
            /* il faut au moins pouvoir écrire un caractère */
     
            if(t > 0)
            {
                i = 0;
     
                /* on arrête la lecture à la fin de ligne, ou lorsque
                qu'il ne reste de la place que pour le caractere
                de fin de chaîne */
     
                while((c = getchar()) != '\n' && c != EOF && i < t-1)
                {
                    s[i++] = c;
                }
     
                /* ajout du caractère de fin de chaîne */
     
                s[i] = 0;
     
                /* s'est-t'on arrêté de lire car on était à la fin de la
                ligne ou parce qu'il fallait réserver une place pour
                le caractère de fin de chaîne ? */
     
                if(c == '\n' || c == EOF)
                {
                    err = ENTREE_OK;
                }
     
                else
                {
                    /* il reste sans doute des caractères dans le flux
                    d'entrée, il faut alors le vider */
     
                    vider_stdin();
                    err = ERR_TAILLE_SAISIE;
                }
            }
     
            else
            {
                err = ERR_TAILLE_TAB;
            }
        }
     
        else
        {
            err = ERR_P_NULL;
        }
     
        return err;
    }
     
    void vider_stdin(void)
    {
        int c;
        while((c = getchar()) != '\n' && c != EOF);
    }
    J'ai choisi pour mes tableaux de char temporaires la taille 16 pour un int, 32 pour un long et 64 pour un double. Je me disais qu'il serait sans doute possible de choisir plus judicieusement ces tailles. Quelles tailles puis-je donc choisir pour éviter d'occuper trop de mémoire mais en même temps pouvoir saisir convenablement les nombres ?

    D'autre part, toute autre remarque sur ces fonctions est bienvenue (elles fonctionnent, mais il y a sans doute possibilité d'améliorer).

    Par avance, merci.

  2. #2
    Membre actif Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    Points : 222
    Points
    222
    Par défaut
    Salut

    Pour un nombre sur 16 bit, tu n'as pas besoins de 16 caractères, mais seulement 5 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    2^16 = 65536 => 5 digits !
    Idem pour les autres nombres !

    Ceci étant valable uniquement pour les nombres entier (attention au signe !)
    "L'expérience est le seul livre que les imbéciles savent lire ... !"

    Qui à dit cela ? Moi je n'sais pas !
    Mais en tout cas, je l'applique au pas !

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 942
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 942
    Points : 5 654
    Points
    5 654
    Par défaut
    lah,
    Citation Envoyé par femtosa
    Salut

    Pour un nombre sur 16 bit, tu n'as pas besoins de 16 caractères, mais seulement 5 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    2^16 = 65536 => 5 digits !
    Idem pour les autres nombres !

    Ceci étant valable uniquement pour les nombres entier (attention au signe !)
    -32000 ?

    Vu que nulle part n'apparaît la précision "non signé"
    Si les cons volaient, il ferait nuit à midi.

  4. #4
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Ah oui, il faut prendre en compte le "-".
    Donc 5 + 1 ("moins") + 1 (fin de chaîne) = 7 caractères suffisent pour un int signé ?

  5. #5
    Membre actif Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    Points : 222
    Points
    222
    Par défaut
    Citation Envoyé par droggo
    lah,

    -32000 ?

    Vu que nulle part n'apparaît la précision "non signé"
    Citation Envoyé par femtosa
    ... (attention au signe !)
    "L'expérience est le seul livre que les imbéciles savent lire ... !"

    Qui à dit cela ? Moi je n'sais pas !
    Mais en tout cas, je l'applique au pas !

  6. #6
    Membre actif Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    Points : 222
    Points
    222
    Par défaut
    Citation Envoyé par odsen.s
    Ah oui, il faut prendre en compte le "-".
    Donc 5 + 1 ("moins") + 1 (fin de chaîne) = 7 caractères suffisent pour un int signé ?
    Exact

    Même réflexion pour n'importe quel entier signé, représenté avec un nombre X de bits
    "L'expérience est le seul livre que les imbéciles savent lire ... !"

    Qui à dit cela ? Moi je n'sais pas !
    Mais en tout cas, je l'applique au pas !

  7. #7
    Membre éclairé 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
    Points : 771
    Points
    771
    Par défaut
    Citation Envoyé par odsen.s
    7 caractères suffisent pour un int signé ?
    Cela dépend de l'architecture. 7 caractères suffisent pour un entier signé sur 16 bits. Sur beaucoup de machines aujourd'hui, les entiers sont codés sur 32 bits, et il faut alors au moins 12 caractères.

  8. #8
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    J'ai choisi pour mes tableaux de char temporaires la taille 16 pour un int, 32 pour un long et 64 pour un double. Je me disais qu'il serait sans doute possible de choisir plus judicieusement ces tailles. Quelles tailles puis-je donc choisir pour éviter d'occuper trop de mémoire
    Comme tu le dis, ces tableaux sont temporaires. Ils sont détruits en sortie de fonction et tu récupères la place mémoire que tu as allouée. Tu n'es donc pas à un octet près (sans exagérer toutefois, puisque les tableaux sont créés sur la pile)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  9. #9
    Membre expérimenté
    Inscrit en
    Décembre 2004
    Messages
    1 478
    Détails du profil
    Informations forums :
    Inscription : Décembre 2004
    Messages : 1 478
    Points : 1 664
    Points
    1 664
    Par défaut
    Citation Envoyé par diogene
    Tu n'es donc pas à un octet près (sans exagérer toutefois, puisque les tableaux sont créés sur la pile)
    Tres juste, d'autant que l'utilisateur (qui est par nature sournois) peut s'amuser a mettre des espaces avant le nombre demande...

  10. #10
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Cela dépend de l'architecture. 7 caractères suffisent pour un entier signé sur 16 bits. Sur beaucoup de machines aujourd'hui, les entiers sont codés sur 32 bits, et il faut alors au moins 12 caractères.
    Ah oui, c'est vrai. Je peux dans ce cas me contenter d'une seule fonction lire_long pour lires les long et les int.

    Comme tu le dis, ces tableaux sont temporaires. Ils sont détruits en sortie de fonction et tu récupères la place mémoire que tu as allouée. Tu n'es donc pas à un octet près (sans exagérer toutefois, puisque les tableaux sont créés sur la pile)
    D'accord

    Par contre, pour le double, qui comporte une partie fractionnaire, je m'y perd un peu pour compter le nombre maximal de chiffres.

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Je voudrais créer des fonctions permettant de saisir correctement au clavier des int, long et doubles. J'ai donc utilisé une fonction permettant de lire une chaîne de caractères au clavier que j'avais déjà créée, et converti cette chaîne grâce à atoi, atol ou atod.

    D'autre part, toute autre remarque sur ces fonctions est bienvenue (elles fonctionnent, mais il y a sans doute possibilité d'améliorer).
    Voici déjà de quoi tester la fonction de lecture de ligne, qui me semble tout à fait correcte et stable.
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
     
    #include <stdio.h>
     
    enum
    {
       ENTREE_OK,
       ERR_TAILLE_SAISIE,
       ERR_TAILLE_TAB,
       ERR_P_NULL,
       ERR_NB
    };
     
    void vider_stdin (void)
    {
       int c;
       while ((c = getchar ()) != '\n' && c != EOF);
    }
     
    /* lire_ligne : lit une ligne sur l'entree standard
    et l'écrit dans un tableau de caractères */
    int lire_ligne (char *s, size_t t)
    {
       int c;
       int err;
       size_t i;
       /* le pointeur doit contenir une adresse */
       if (s != NULL)
       {
          /* il faut au moins pouvoir écrire un caractère */
          if (t > 0)
          {
             i = 0;
             /* on arrête la lecture à la fin de ligne, ou
                lorsque qu'il ne reste de la place que pour le
                caractere de fin de chaîne */
             while ((c = getchar ()) != '\n' && c != EOF && i < t - 1)
             {
                s[i++] = c;
             }
             /* ajout du caractère de fin de chaîne */
             s[i] = 0;
             /* s'est-t'on arrêté de lire car on était à la
                fin de la ligne ou parce qu'il fallait réserver
                une place pour le caractère de fin de chaîne ? */
             if (c == '\n' || c == EOF)
             {
                err = ENTREE_OK;
             }
             else
             {
                /* il reste sans doute des caractères dans le
                   flux d'entrée, il faut alors le vider */
                vider_stdin ();
                err = ERR_TAILLE_SAISIE;
             }
          }
          else
          {
             err = ERR_TAILLE_TAB;
          }
       }
       else
       {
          err = ERR_P_NULL;
       }
       return err;
    }
     
    int main (void)
    {
       char s[5];
       int err;
       do
       {
          err = lire_ligne (s, sizeof s);
     
          if (!err)
          {
             printf ("'%s'\n", s);
          }
          else
          {
             printf ("erreur %d\n", err);
          }
       }
       while (err || *s != 0);
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Ah oui, il faut prendre en compte le "-".
    Donc 5 + 1 ("moins") + 1 (fin de chaîne) = 7 caractères suffisent pour un int signé ?
    Non. Ca dépend des limites d'un int sur ton implémentation. Cette formule m'a été donnée pour un long :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    /* (c) Eric Sosman 2001 */
    #define BIG_ENOUGH (1 + (sizeof(long) * CHAR_BIT + 2) / 3 + 1)
    Pas de Wi-Fi à la maison : CPL

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Par contre, pour le double, qui comporte une partie fractionnaire, je m'y perd un peu pour compter le nombre maximal de chiffres.
    Ca peut être énorme. Là encore, ça dépend des valeurs de ton implémentation (<float.h>). Pour déclencher un ERANGE en mode décimal, il faut plus de 300 caractères...

    Pour les saisies numériques, il faut être beaucoup plus sérieux que atoi() ou atof() qui sont (depuis bientôt 20 ans) remplacées par strtol(), strtoul() et strtod().

    Ces fonctions permettent de savoir si on a saisi le nombre correctement et de déclencher ERANGE si nécessaire (strtod())
    Pas de Wi-Fi à la maison : CPL

  14. #14
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Non. Ca dépend des limites d'un int sur ton implémentation. Cette formule m'a été donnée pour un long :
    Code :

    /* (c) Eric Sosman 2001 */ #define BIG_ENOUGH (1 + (sizeof(long) * CHAR_BIT + 2) / 3 + 1)
    Cette formule prend elle en compte le caractère de fin de chaîne, ou faut-il rajouter 1 ?

    Ca peut être énorme. Là encore, ça dépend des valeurs de ton implémentation (<float.h>). Pour déclencher un ERANGE en mode décimal, il faut plus de 300 caractères...
    Puisque l'on peut stocker un nombre allant de 1E-37 à 1E37, ça fait donc 38 chiffres maxi devant le point et 37 après, donc 38 + 1 (le point) + 37 + 1 (fin de chaîne) = 77 caractères ? J'ai du mal à comprendre comment en stocker jusqu'à 300.

    Je vais commencer par regarder comment fonctionnent strtol(), strtoul() et strtod() et les utiliser dans mes fonctions.

    Merci pour l'aide fournie

    EDIT : après avoir mieux regardé mon K&R2 p257 <stdlib.h>, je constate que atof(const char *s) est en fait équivalent à strtod(s, (char**) NULL). Pourquoi préférer la seconde fonction alors, si je ne veux pas enregistrer la partie non convertie ?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Cette formule prend elle en compte le caractère de fin de chaîne, ou faut-il rajouter 1 ?
    Visiblement, il y a un +1 à la fin, non ?
    Puisque l'on peut stocker un nombre allant de 1E-37 à 1E37, ça fait donc 38 chiffres maxi devant le point et 37 après, donc 38 + 1 (le point) + 37 + 1 (fin de chaîne) = 77 caractères ? J'ai du mal à comprendre comment en stocker jusqu'à 300.
    Chez moi, c'est plutôt 1E308 ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    DBL_MAX = 1.79769e+308
     
    Press ENTER to continue.
    avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    #include <stdio.h>
    #include <float.h>
     
    int main (void)
    {
       printf ("DBL_MAX = %g\n", DBL_MAX);
     
       return 0;
    }
    Pas de Wi-Fi à la maison : CPL

  16. #16
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    odsen.s a écrit :
    Cette formule prend elle en compte le caractère de fin de chaîne, ou faut-il rajouter 1 ?
    Visiblement, il y a un +1 à la fin, non ?
    Oui, simple vérification

    Chez moi, c'est plutôt 1E308 ...
    En effet, je m'étais basé sur le DBL_MAX donné p264 K&R, mais je n'avais pas vérifié la valeur.
    Je vois aussi que DBL_MIN vaut 2.22507e-308.
    Peut-on stocker un nombre ayant à la fois 309 chiffres avant la virgule et 308 derrière, ou bien est-ce l'un ou l'autre ?

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Oui, simple vérification


    En effet, je m'étais basé sur le DBL_MAX donné p264 K&R, mais je n'avais pas vérifié la valeur.
    Je vois aussi que DBL_MIN vaut 2.22507e-308.
    Peut-on stocker un nombre ayant à la fois 309 chiffres avant la virgule et 308 derrière, ou bien est-ce l'un ou l'autre ?
    Non. En gros, c'est 99999....9999999 308 fois....

    Avec une tableau de 512, on est tranquille en 32-bit...
    Pas de Wi-Fi à la maison : CPL

  18. #18
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    D'accord, un tableau de 512 fera l'affaire alors.

    (As-tu remarqué que j'avais édité mon message #14 pour poser une autre question ?)

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    EDIT : après avoir mieux regardé mon K&R2 p257 <stdlib.h>, je constate que atof(const char *s) est en fait équivalent à strtod(s, (char**) NULL). Pourquoi préférer la seconde fonction alors, si je ne veux pas enregistrer la partie non convertie ?
    La question n'est pas là. L'usage du 2 ème paramètre permet de déterminer si la conversion est correcte ou si il y'a des caractères erronés. En principe, *pend doit valoir 0. Dans les autres cas, le format est incorrect (ou on analyse une chaine avec plusieurs valeurs...).
    Pas de Wi-Fi à la maison : CPL

  20. #20
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Très bien, merci

    Voici mes nouvelles fonctions :
    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
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    /* lire_long : lit une chaine de caracteres et convertit en long */
     
    int lire_long(long *l)
    {
        int err;
        char temp[NB_CAR_LONG] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            char *p_conversion = NULL;
            *l = strtol(temp, &p_conversion, 10);
     
            if(*p_conversion != 0)
            {
                err = ERR_FORMAT;
            }
        }
     
        return err;
    }
     
     
    /* lire_ulong : lit une chaine de caracteres et convertit en long non signé */
     
    int lire_ulong(unsigned long *ul)
    {
        int err;
        char temp[NB_CAR_LONG] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            char *p_conversion = NULL;
            *ul = strtoul(temp, &p_conversion, 10);
     
            if(*p_conversion != 0)
            {
                err = ERR_FORMAT;
            }
        }
     
        return err;
    }
     
     
    /* lire_double : lit une chaine de caracteres et convertit en double */
     
    int lire_double(double *lf)
    {
        int err;
     
        char temp[512] = {0};
     
        if((err = lire_ligne(temp, sizeof temp)) == ENTREE_OK)
        {
            char *p_conversion = NULL;
            *lf = strtod(temp, &p_conversion);
     
            if(*p_conversion != 0)
            {
                err = ERR_FORMAT;
            }
        }
     
        return err;
    }
    Les tests paraissent bons.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. fonction pour concaténer des nombres
    Par fiatlux dans le forum XSL/XSLT/XPATH
    Réponses: 10
    Dernier message: 11/10/2011, 11h15
  2. Fonction pour lire des nombres dans un fichier
    Par passant_ dans le forum Débuter
    Réponses: 11
    Dernier message: 28/10/2008, 18h47
  3. Créer une fonction pour remplacer des caractères
    Par virtuadrack dans le forum C++
    Réponses: 4
    Dernier message: 11/09/2008, 14h52
  4. fonction pour comparer des nombres
    Par insa59 dans le forum Débuter
    Réponses: 5
    Dernier message: 21/06/2007, 10h34
  5. Creation d'un composant pour saisir des nombres
    Par Sylmandel dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 05/06/2006, 10h09

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