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 :

Gérer une erreur d'encodage


Sujet :

C

  1. #1
    Membre régulier Avatar de arkham55
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 179
    Points : 74
    Points
    74
    Par défaut Gérer une erreur d'encodage
    Bonsoir tout le monde,

    Alors voici mon mini problème, je voudrai que l'utilisateur entre un nom, mais lorsqu'il entre un nom trop long (20 caractères maximum) il doive répéter l'opération jusqu'à ce que ce soit ok. J'ai donc penser à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	printf ("Entrez son nom: ");
    	gets (aide);
    	EspaceToTiret(aide,strlen(aide));
    	taille=strlen(aide);
    	while(taille>20){
    	  printf ("Recommencez: (20 caractères) ");
    	  gets(aide);
     
    	  taille=strlen(aide);
    	}
    	EspaceToTiret(aide,strlen(aide));
    	strcpy(courant->nom, aide);
    En faisant comme ceci, logiquement cela devrait fonctionner tranquillement. Excepté lorsque l'on entre un nom trop long, car ensuite quand on entre un nom de taille correcte, il m'affiche une erreur de segmentation. Et c'est l'instruction strcpy(...) l'origine de l'erreur...
    Je ne vois pas pourquoi cela se produit, d'autant plus que lorsque j'affiche le contenu de la variable aide juste avant la copie, c'est ok.
    C'est à ... que vous ... le plus de mystères.

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Le problème c'est gets et rien d'autre. gets laisse à l'utilisateur la possibilité d'entrer une chaîne plus longue que ce que la destination peut contenir, c'est une fonction à bannir. Utilise fgets à la place.

  3. #3
    Membre régulier Avatar de arkham55
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 179
    Points : 74
    Points
    74
    Par défaut
    merci de ta réponse Melem.
    J'ai testé avec la fonction fgets mais cela ne fonctionne pas, ne serait-ce pas avec un fichier que l'on utilise cette fonction?
    J'ai également essayé avec scanf mais le diagnostic de l'erreur de segmentation est le même, cela provient de strcpy. Je trouve cela bizarre tout de même mais lorsque je le "commentarise", pas d'erreur.
    C'est à ... que vous ... le plus de mystères.

  4. #4
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    D'abord il faut que tu remplaces gets par fgets, ça ce n'est pas discutable. Oui c'est pour les fichiers, mais l'entrée standard (qui est souvent attaché par défaut au clavier), stdin, est aussi un fichier ... regarde bien les codes de la FAQ.

    Ensuite, si strcpy provoque une erreur de segmentation, c'est que courant->nom n'est pas un tableau. Peut-être est-ce un pointeur sur char (char *) ? Dans ce cas le plantage est garanti. Le mieux est que tu postes ton code complet pour qu'on puisse facilement et rapidement corriger.

  5. #5
    Membre régulier Avatar de arkham55
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 179
    Points : 74
    Points
    74
    Par défaut
    J'ai déclaré une structure "contact" où l'on retrouve différents attributs (nom, prénom, etc). Donc, le nom qui est déclaré tel que "char[22]" ce qui ne permet donc pas d'entrer un nom de plus de 20 caractères. Et c'est cette exception que je veux gérer dans mon programme.
    Je vais consulter l'API.
    C'est à ... que vous ... le plus de mystères.

  6. #6
    Membre régulier Avatar de arkham55
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 179
    Points : 74
    Points
    74
    Par défaut
    Voilà, j'ai bien épluché tes tutoriels et je dois dire qu'ils sont vraiment bien réalisés, clairs et utiles =)
    J'ai remarqué que lorsque tu montres un exemple où l'utilisateur doit encoder, tu utilises scanf. J'utilisais cette fonction également jusqu'à ce que je me rende compte que lorsque l'on entrait un espace, il passait à l'encodage du suivant automatiquement.
    C'est pour cela que j'ai utilisé gets par la suite...
    C'est à ... que vous ... le plus de mystères.

  7. #7
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    J'ai remarqué que lorsque tu montres un exemple où l'utilisateur doit encoder, tu utilises scanf
    Normal, c'est celle qui est la plus simple à introduire et à utiliser dans les cas les plus triviaux.

    J'utilisais cette fonction également jusqu'à ce que je me rende compte que lorsque l'on entrait un espace, il passait à l'encodage du suivant automatiquement.
    C'est le code "%s" qui cause cela, ce n'est pas intrinsèque à scanf. Si tu mets par exemple "%[^\n]" à la place de "%s", cela entraine la saisie d'une chaîne, tous les caractères autorisés sauf le \n (les crochets délimitent les caractères acceptables et le ^ indique que ce qui suit doit provoquer l'arrêt de la lecture des caractères). Si t'es nouveau dans le C, maîtriser scanf n'est pas ta priorité. Mais si cela t'intéresse, tu peux toujours lire les divers tutoriels du site ou directement te taper la norme.

    C'est pour cela que j'ai utilisé gets par la suite...
    On ne te blâmera pas pour ça. Mais maintenant que tu "sais", on te blâmera la prochaine fois que tu utilises encore gets .

  8. #8
    Membre régulier Avatar de arkham55
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    179
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2010
    Messages : 179
    Points : 74
    Points
    74
    Par défaut
    Bonjour bonjour!

    Voilà, j'ai beaucoup cherché mais pas en vain! ^__^
    Je suis parvenu à mes fins grâce à la fonction fgets. Elle est sympa quand on la connait bien

    Voici comment j'ai procédé :

    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
     
            int taille = 0;
            char aide[22];
     
    	printf ("Entrez son nom: ");
    	fgets(aide, sizeof aide, stdin);
    	exception(aide);
    	EspaceToTiret(aide,strlen(aide));
    	taille=strlen(aide);
    	while(taille>20){
    	  printf ("Recommencez: (20 caractères) ");
    	  fgets(aide, sizeof aide, stdin);
    	  exception(aide);
    	  taille=strlen(aide);
    	}
    	EspaceToTiret(aide,strlen(aide));
    	strcpy(courant->nom, aide);
    petit résumé de mes trouvailles pour les personnes qui désireraient faire de même :

    Premièrement, fgets :
    ---------------------
    Voici une petite présentation de son prototype qui se révèle comme suit
    fgets(char* chaine, int tailleChaine, FILE *fichier);
    Il permet de récupérer une chaîne de caractère d'une taille définie, à partir d'un fichier (ou de l'entrée standard, stdin, soit le clavier mes amis!).

    Ensuite, la fonction exception :
    ------------------------------
    Elle va permettre de supprimer le caractère spécial '\n' qui poserait problème sinon ;s On va en fait le nier! Et pour cela, on utilise la fonction standard strchr(chaine, 'caractère') (de la librairie string.h) pour localiser le vilain '\n' .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    static void exception (char *chaine){
      char *p = strchr (chaine, '\n');
      if (p)
        {
            *p = 0;
        }
      else
      {
        vider();
      }
    }
    Une fois ce problème réglé, un autre surgit des entrailles de la Terre >_< Un démon que j'ai nommé "dépassement de la taille définie"!

    Remède ; la fonction vider :
    ---------------------------

    Si on a le malheur de saisir une entrée trop longue, ce qu'on a entré est stocké dans un buffer, stdin pour l'entrée standard (clavier). Celui-ci va être vidé progressivement, si je peux m'exprimer ainsi, et il fera le tour de la boucle while jusqu'à ce qu'il n'y ait plus de caractères en mémoire. Or, ce que nous voulons, c'est qu'il réitère la demande d'entrée si la taille est dépassée. On va donc vider le buffer avec la fonction vider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    static void vider(void)
    {
        int c;
     
        while ((c = getchar()) != '\n' && c != EOF)
        {}
    }
    En mettant tout cela ensemble, plus de problèmes de gets ou de dépassement. =)
    C'est à ... que vous ... le plus de mystères.

Discussions similaires

  1. Gérer une erreur
    Par francoisch dans le forum Langage
    Réponses: 9
    Dernier message: 03/01/2011, 17h06
  2. gérer une erreur TJvDatePickerEdit (TDateTimePicker)
    Par yaniss321 dans le forum Langage
    Réponses: 0
    Dernier message: 12/01/2010, 16h28
  3. Gérer une erreur
    Par KonTiKI dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 22/02/2009, 19h14
  4. Gérer une erreur d'intégrité mysql(1451)
    Par spitou_77 dans le forum VBA Access
    Réponses: 0
    Dernier message: 29/11/2007, 09h47
  5. Réponses: 1
    Dernier message: 17/09/2006, 10h45

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