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

Vue hybride

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    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 éclairé Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    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 !)

  3. #3
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 967
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 967
    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é"

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

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    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 éclairé Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    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

  6. #6
    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
    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.

  7. #7
    Expert confirmé
    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
    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)

  8. #8
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    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 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)

  9. #9
    Membre éclairé Avatar de femtosa
    Inscrit en
    Juin 2002
    Messages
    253
    Détails du profil
    Informations forums :
    Inscription : Juin 2002
    Messages : 253
    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 !)

  10. #10
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    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 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;
    }

+ Répondre à la discussion
Cette discussion est résolue.

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