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

Bibliothèque standard C Discussion :

Probleme avec fgets


Sujet :

Bibliothèque standard C

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Points : 63
    Points
    63
    Par défaut Probleme avec fgets
    Bonjour,

    j'ai déjà posté il y a un une semaine. J'avais des soucis de saisie au clavier à cause des scanf.

    J'ai tout remplacé par des fgets et j'ai crée une fonction "saisieChaine" qui renvoie une chaine saisie au clavier en supprimant le saut de ligne (en m'inspirant fortement de ce que j'ai trouvé sur le forum).

    Je n'ai pas utilisé fclean car le seul lien que j'ai trouvé dans les archives est mort .
    Je pensais que la fonction que j'avais là était équivalente à fclean mais j'ai du me tromper quelquepart.

    Voici le code :
    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
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define NMAX 100
     
    char* saisieChaine();
    void vider_stdin(void);
     
    main(){
      int nbPays,i,j;
      char *nomsPays[NMAX];
     
    // Saisie des pays
      do{
        printf("Nombre de pays : ");
        nbPays=atoi(saisieChaine()); //Convertit la chaine entree au clavier en entier
      }while(nbPays<2 || nbPays>NMAX);
     
      printf("Entrez le nom des pays :\n");
      for(i=0;i<nbPays;i++){
        printf("- ");
        nomsPays[i]=saisieChaine();
        printf("nomsPays[%d]=%s\n",i,nomsPays[i]);
        printf("nomsPays[%d]=%s\n",i,nomsPays[i]);
      }
    }
     
    char* saisieChaine(){
      char *pc; //Supprime le saut de ligne
      char chaine[100];
      int saisie_OK = 0;
     
      while (saisie_OK == 0){
        fflush(stdout);
        fgets(chaine, sizeof chaine, stdin);
        if ((pc = strchr(chaine, '\n')) != NULL){
          *pc = '\0';
          saisie_OK = 1;
        }
        else{
          fprintf(stderr, "Saisie trop longue, recommencez\n");
          vider_stdin();
        }
      }
      return chaine;
    }
     
    void vider_stdin(void){
        scanf("%*[^\n]");
        getchar(); 
    }
    Les deux printf successif m'affichent de résultats différents (le premier me donne la bonne chaine et pas le suivant).

    Si vous pouvez me dire ce qui cloche et pourquoi a m'aiderais beaucoup ^^
    (évitez de juste me dire d'utiliser fclean puisque je n'arrive pas à trouver l'éxplication claire de cette fonction et que ce que j'ai essayé d'adapter ne marche pas, je serais toujours aussi perdu).

    Merci d'avance !

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Décembre 2002
    Messages
    534
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2002
    Messages : 534
    Points : 403
    Points
    403
    Par défaut
    Salut,

    Essayons d'abord de donner à SaisieChaine une chaîne à saisir par ex SaisieChaine( char * une_chaine ) ...

  3. #3
    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 SAKDOSS Voir le message
    j'ai déjà posté il y a un une semaine. J'avais des soucis de saisie au clavier à cause des scanf.

    J'ai tout remplacé par des fgets et j'ai crée une fonction "saisieChaine" qui renvoie une chaine saisie au clavier en supprimant le saut de ligne (en m'inspirant fortement de ce que j'ai trouvé sur le forum).

    Je n'ai pas utilisé fclean car le seul lien que j'ai trouvé dans les archives est mort .
    5 minutes de recherches :

    http://www.developpez.net/forums/sho...2&postcount=24
    Je pensais que la fonction que j'avais là était équivalente à fclean mais j'ai du me tromper quelquepart.

    Voici le code :
    Je ne connais pas scanf(), alors je ne sais pas si l'usage que tu en fais est correct.

    Ton code comporte une erreur grave. Tu retournes l'adresse d'une variable locale, ce qui n'a aucun sens, vu que la variable n'existe plus après exécution de la fonction.

    Ceci 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
    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
     
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define NMAX 100
     
    #include <string.h>
     
    int fclean (char *s_buffer, FILE * stream)
    {
       int err = 0;
       if (s_buffer != NULL && stream != NULL)
       {
          char *pc = strchr (s_buffer, '\n');
     
          if (pc != NULL)           /* La saisie n'a pas ete tronquee */
          {
             /* On remplace '\n' par le caractere nul '\0' */
             *pc = 0;
          }
          else
          {
             /* La saisie a ete tronquee, on purge le flux d'entree */
             int c;
             while ((c = fgetc (stream)) != '\n' && c != EOF)
             {
             }
             err = 1;
          }
       }
       return err;
    }
     
    void saisieChaine (char *chaine, size_t size)
    {
       int saisie_OK = 0;
     
       while (saisie_OK == 0)
       {
          fgets (chaine, size, stdin);
          {
             saisie_OK = !fclean (chaine, stdin);
             if (!saisie_OK)
             {
                fprintf (stderr, "Saisie trop longue, recommencez\n");
             }
          }
       }
    }
     
    int main (void)
    {
       char nomsPays[NMAX][128];
       int nbPays;
     
    // Saisie des pays
       do
       {
          char s[32];
          printf ("Nombre de pays : ");
     
          saisieChaine (s, sizeof s);
          nbPays = atoi (s);        //Convertit la chaine entree au clavier en entier
       }
       while (nbPays < 2 || nbPays > NMAX);
     
       printf ("Entrez le nom des pays :\n");
       {
          int i;
          for (i = 0; i < nbPays; i++)
          {
             printf ("- ");
             saisieChaine (nomsPays[i], sizeof nomsPays[i]);
          }
     
          for (i = 0; i < nbPays; i++)
          {
             printf ("nomsPays[%d]=%s\n", i, nomsPays[i]);
          }
       }
       return 0;
    }
    Si tu veux faire une saisie souple avec allocation dynamique, et conserver le tableau de pointeurs, il faut procéder autrement.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Points : 63
    Points
    63
    Par défaut
    Merci pour vos réponses.

    Effectivement j'ai fais quelque chose de très moche.

    Par contre en parlant de la fonction fclean je voulais dire que je n'avais pas réussi à en trouver d'explication (sous forme écrite pas sous forme de code ^^). Je ne maitrise pas totalement donc j'ai encore du mal à comprendre avec le code.

    Dailleurs si ça ne te dérange pas j'ai quelques questions plus ou moins évidentes à te poser sur ce que tu m'as envoyé Emmanuel :

    1) "static int fclean" veux dire que l'on renvoit une constante il me semble. Quelle est l'utilitée de static ?

    2) " *pc = 0; " est-il équivalent à " *pc = '\0' " ?

    3) La ligne qui sert à purger le flux :
    "while ((c = fgetc (stream)) != '\n' && c != EOF)"
    veux dire qu'un flux est toujours limité à une ligne ?

  5. #5
    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 SAKDOSS Voir le message
    1) "static int fclean" veux dire que l'on renvoit une constante il me semble. Quelle est l'utilitée de static ?
    Eviter un clash chez moi ! Je le retire.
    2) " *pc = 0; " est-il équivalent à " *pc = '\0' " ?
    Oui.
    3) La ligne qui sert à purger le flux :
    "while ((c = fgetc (stream)) != '\n' && c != EOF)"
    veux dire qu'un flux est toujours limité à une ligne ?
    Ici, ce qu'on cherche à purger, c'est la dernière ligne saisie si elle n'est pas complète.

    Nota : c'est une stratégie comme une autre (on considère ici que les données non lues sont perdues). Il existe d'autres stratégies qui consistent à récupérer les données coute que coute en utilisant l'allocation dynamique. Mais je ne crois pas que tu en sois arrivé là. Un problème à la fois...

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    121
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 121
    Points : 63
    Points
    63
    Par défaut
    Ok merci beaucoup

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

Discussions similaires

  1. Probleme avec fgets()
    Par Piscium dans le forum C
    Réponses: 4
    Dernier message: 13/07/2010, 09h38
  2. probleme avec fgets et un tableau à 2 dimensions
    Par l1086 dans le forum Bibliothèque standard
    Réponses: 16
    Dernier message: 14/12/2007, 19h43
  3. probleme avec fgets
    Par loan33 dans le forum Langage
    Réponses: 2
    Dernier message: 01/12/2006, 18h24
  4. probleme avec fgets
    Par semaj_james dans le forum C
    Réponses: 3
    Dernier message: 09/12/2005, 21h00
  5. [Kylix] probleme avec un imagelist
    Par NicoLinux dans le forum EDI
    Réponses: 4
    Dernier message: 08/06/2002, 23h06

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