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 :

Controle de la saisie


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Inscrit en
    Septembre 2005
    Messages
    747
    Détails du profil
    Informations forums :
    Inscription : Septembre 2005
    Messages : 747
    Par défaut Controle de la saisie
    Bonjour,

    j'ai écrit un main permettant de savoir si le nombre donné en ligne de commande est correct.
    Le problème est que si un entier négatif est donné mon programme m'affiche n'importe quoi.
    Je voudrais savoir comment modifier mon main pour être sur que l'entier donné en ligne de commande sera positif

    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <limits.h>
     
    int etrange(unsigned long int x){
      return x>9UL ? -1 : '0'+(int)x;
    }
     
    char *bizarre(unsigned long int x, unsigned int z, unsigned long int d){
      static char y[BUFSIZ];
      int k = etrange(x/d);
      if(k!=-1)
        y[z+1] = '\0';
      else{
        (void)bizarre(x, z+1U, d*10UL);
        k = etrange((x/d)%10UL);
      }
      y[z] = (char)k;
      return y;
    }
     
    char *mystere(unsigned long int x){
      return bizarre(x, 0U, 1UL);
    }
     
    int main(int argc, char *argv[]){
      unsigned long ul;
      char *e;
      if(argc!=2){
        fprintf(stderr,"Erreur : nombre de parametres incorrect !\n");
        return EXIT_FAILURE;
      }
      errno = 0;
      ul=strtoul(argv[1],&e,10);
      if((ul == ULONG_MAX && errno == ERANGE) || (*e!='\0')){
        fprintf(stderr,"Erreur de traitement du parametre !\n");
        return EXIT_FAILURE;
      } 
      printf("%s\n", mystere(ul));
      return EXIT_FAILURE;
    }

  2. #2
    Expert confirmé

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Par défaut
    En ajoutant :

    et en ajoutant ce test :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           if((ul == ULONG_MAX && errno == ERANGE) || (*e!='\0') || (strchr(argv[1],'-'))){
    Cela devrait suffir...

    Jc

  3. #3
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 395
    Par défaut
    strtoul() aura du mal à parser un nombre négatif...
    Pourquoi ne pas utiliser strtol() ?
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  4. #4
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par Médinoc
    strtoul() aura du mal à parser un nombre négatif...
    Hé non, strtoul() a bien le droit de parser des nombres négatifs et de les convertir en unsigned long si il y a arrive, là est le vice.

    A+

  5. #5
    Membre chevronné
    Avatar de Foobar1329
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Juin 2006
    Messages : 283
    Par défaut
    Hello,

    Citation Envoyé par Premium
    Bonjour,

    j'ai écrit un main permettant de savoir si le nombre donné en ligne de commande est correct.
    Le problème est que si un entier négatif est donné mon programme m'affiche n'importe quoi.
    Je voudrais savoir comment modifier mon main pour être sur que l'entier donné en ligne de commande sera positif
    Utiliser strtol() à la place de strtoul() par exemple, comme ça tu récupères un entier signé et tu n'as plus qu'à le comparer à zéro. Mais regardons le pourquoi à partir d'un entier négatif tu as l'impression de récupérer n'importe quoi avec mystere() (car ce n'est pas le cas).

    Citation Envoyé par Premium
    [CODE]
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <limits.h>

    int etrange(unsigned long int x){
    return x>9UL ? -1 : '0'+(int)x;
    }

    char *bizarre(unsigned long int x, unsigned int z, unsigned long int d){
    static char y[BUFSIZ];
    int k = etrange(x/d);
    if(k!=-1)
    y[z+1] = '\0';
    else{
    (void)bizarre(x, z+1U, d*10UL);
    k = etrange((x/d)%10UL);
    }
    y[z] = (char)k;
    return y;
    }

    char *mystere(unsigned long int x){
    return bizarre(x, 0U, 1UL);
    }

    [CODE]
    mystere() appelle bizarre(), cette dernière s'appelant récursivement. Tu prends d'abord le chiffre des unités, puis ensuite celui des dizaines, puis celui des centaines, etc... Bref, c'est presque un atoi() à l'envers.

    Tout va bien en fait, le seul problème, qui n'en est pas un, vient de strtoul(). Cette dernière a très bien le droit de convertir un entier signé en base 10 en entier non signé.

    La norme dit dans §6.3.1.3 :
    "Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type."
    Ce qui veut dire qu'on ajoute ce qu'il faut de nécessaire à chaque valeur de l'ancien type et qui n'est pas représentable dans le nouveau type, pour qu'elle soit représentable dans le nouveau type.

    Par exemple pour une conversion de int en unsigned int, les valeurs entre INT_MIN et -1 vont correspondre au valeurs entre INT_MAX+1 et UINT_MAX.

    Ainsi, si tu entres -1 avec ton programme, cela devient [edit: UINT_MAX => ULONG_MAX] et mystere() affiches bien la chaine correspondante à l'envers.

    Un printf() de ul dans ton programme permet de le constater, cf modif en gras.

    Citation Envoyé par Premium
    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
    
    int main(int argc, char *argv[]){
      unsigned long ul;
      char *e;
      if(argc!=2){
        fprintf(stderr,"Erreur : nombre de parametres incorrect !\n");
        return EXIT_FAILURE;
      }
      errno = 0;
      ul=strtoul(argv[1],&e,10);
      if((ul == ULONG_MAX && errno == ERANGE) || (*e!='\0')){
        fprintf(stderr,"Erreur de traitement du parametre !\n");
        return EXIT_FAILURE;
      } 
    
    /*  printf("%s\n", mystere(ul));
         return EXIT_FAILURE;
    */
      printf("%lu %s\n", ul, mystere(ul));
      return EXIT_SUCCESS;
    
    }
    Juste un pb de conversion entre entiers, vraiment pas ce qu'il ya de plus facile en C.

    A+

Discussions similaires

  1. Controle de la saisie dans un JPasswordField
    Par peute dans le forum AWT/Swing
    Réponses: 6
    Dernier message: 04/06/2007, 12h18
  2. controle js sur saisie N° telephone
    Par fraizas dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 26/03/2007, 11h15
  3. Controler si une saisie est numerique
    Par Rodrick dans le forum Visual C++
    Réponses: 5
    Dernier message: 07/03/2007, 12h13
  4. Controle de la saisie dans un textbox
    Par jpp81 dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 24/11/2006, 05h48
  5. Contrôle sur données saisies dans un formulaire
    Par omega dans le forum Langage
    Réponses: 2
    Dernier message: 17/08/2006, 16h55

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