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 :

scanf vs fgets


Sujet :

C

  1. #41
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void pause(const char *s_message)
    {
        char c[256];
        if (strlen(s_message) != 0)
            fprintf(stdout, "%s", s_message);
        else if(s_message==NULL)
             fprintf(stderr, "Erreur avec le pointeur");
        fflush(stdin);
        fgets(c, sizeof c, stdin);
        fclean(c, stdout);
    }
    Un ami m'a aidé pour la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if (strlen(s_message) != 0)
    Si je presse entrer c'est bon mais si j'appui sur une autre touche ca entre le caractère ce qui est tout à fait normal sachant que j'utilie fgets !
    Comment puis-je régler cela ?

    Merci d'avance
    Peut-être pourrais-tu commencer la fonction avec quelque chose comme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if (s_message != NULL)
    {
       /* SUite du code */
    }
    De plus, on n'utilise jamais fflush() sur stdin (comportement indéfini), mais ici, je pense que c'est une erreur. Finalement, pourquoi ton tampon contient-il 256 caractères (c'est beaucoup pour n'en saisir qu'un seul).

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  2. #42
    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 _SamSoft_ Voir le message
    Si je presse entrer c'est bon mais si j'appui sur une autre touche ca entre le caractère ce qui est tout à fait normal sachant que j'utilie fgets !
    Comment puis-je régler cela ?
    Tu ne peux pas empêcher l'utilisateur de taper ce qu'il veut... Ca n'a aucune importance.

    J'ai toujours des questions non résolues :
    • Que se passe-t-il si s_message vaut NULL ?
    • Pourquoi 256 caractères pour saisir un simple <enter> ?
    • Pourquoi tu passes stdout à fclean() ?

    et des nouvelles questions
    • D'où sors-tu ce fflush(stdin) ?

  3. #43
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void pause(const char *s_message)
    {
        char c[2];
        if (strlen(s_message) != 0)
            fprintf(stdout, "%s", s_message);
        else if(s_message==NULL)
             fprintf(stderr, "Erreur avec le pointeur");
        fflush(stdin);
        fgets(c, sizeof c, stdin);
        fclean(c, stdin);
    }
    Pour s_message et NULL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    else if(s_message==NULL)
    Pour fflush, si je ne le met pas, le texte contenu dans s_message ne s'affiche pas !

    Pour stdout à fclean, c'est une erreur de ma part, je n'avais pas vu.

  4. #44
    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 _SamSoft_ Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    void pause(const char *s_message)
    {
        char c[2];
        if (strlen(s_message) != 0)
            fprintf(stdout, "%s", s_message);
        else if(s_message==NULL)
             fprintf(stderr, "Erreur avec le pointeur");
        fflush(stdin);
        fgets(c, sizeof c, stdin);
        fclean(c, stdin);
    }
    Pour s_message et NULL :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    else if(s_message==NULL)
    Pour la 3ème fois, je repose la question :

    Que se passe-t-il si on passe NULL à la fonction pause() ?

    J'aimerais bien une réponse détaillée.
    Pour fflush, si je ne le met pas, le texte contenu dans s_message ne s'affiche pas !
    Si c'est ça le problème, c'est fflush(stdout) qu'il faut mettre... Tu confonds les deux ou quoi ?
    Pour stdout à fclean, c'est une erreur de ma part, je n'avais pas vu.
    Pourtant signalée...

  5. #45
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Pour la 3ème fois, je repose la question :

    Que se passe-t-il si on passe NULL à la fonction pause() ?

    J'aimerais bien une réponse détaillée.

    Si c'est ça le problème, c'est fflush(stdout) qu'il faut mettre... Tu confonds les deux ou quoi ?
    Pourtant signalée...
    Pour le problème de NULL, pouvez vous me donner un exemple J'ai pas compris.

    Pour flush, j'ai bien mis stdout mais ca ne marchait toujours pas alors j'ai mis stdin et là ca fonctionne !

  6. #46
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Ben NULL à strlen ça plante je pense.

    Il faut que tu inverses ton if, tu fais d'abord le strlen et ensuite tu testes si c'est = NULL.

  7. #47
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Comme ceci ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    void pause(const char *s_message)
    {
        char c[2];
        if (strlen(s_message) != 0 && s_message!=NULL)
            fprintf(stdout, "%s", s_message);
        fflush(stdin);
        fgets(c, sizeof c, stdin);
        fclean(c, stdin);
    }

  8. #48
    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 _SamSoft_ Voir le message
    Pour le problème de NULL, pouvez vous me donner un exemple J'ai pas compris.
    C'est simple. Si c_message vaut NULL, c'est cette valeur que tu passes à strlen(). Or passer NULL à strlen(), comme l'indique sa documentation, provoque un comportement indéfini. Tout peut arriver.

    D'autre part, je n'ai pas demandé qu'un message soit affiché en cas de NULL, mais simplement que rien ne soit affiché du tout. Il faut donc revoir ton algorithme en conséquence.

    C'est assez basique...
    Pour flush, j'ai bien mis stdout mais ca ne marchait toujours pas alors j'ai mis stdin et là ca fonctionne !
    Tss... La programmation, c'est pas du hasard. Il est certain que ça doit fonctionner avec fflush(stdout). Si ce n'est pas le cas, c'est qu'il y a un autre problème.

    D'autre part, fflush(stdin) n'existe pas (comportement indéfini comme déjà signalé).

  9. #49
    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 _SamSoft_ Voir le message
    Comme ceci ? :
    Non. Réfléchis avant de coder ou de poser une question. On est pas sur un chat ici. On se pose, et on prend du temps...

    Personne ne code au hasard. Tout a une logique parfaitement claire.

  10. #50
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Je réflechis ! Mais je ne vois vraiment pas !

  11. #51
    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 _SamSoft_ Voir le message
    Je réflechis ! Mais je ne vois vraiment pas !
    C'est pourtant simple. Pour que le message soit affiché, il faut respecter 2 conditions :

    - Le pointeur n'est pas NULL
    - La chaine a une longueur non nulle.

    On t'a donné l'idée de tester la longueur de la chaine avec strlen(), OK. Problème, si on passe un NULL à strlen(), pour faire simple, ça plante.

    Donc il faut traiter les conditions dans un ordre bien précis qui fait que quand on teste la longueur, on est sûr que le pointeur n'est pas NULL.

    A toi de jouer.

    Ce petit problème est très simple... Je ne sais pas ce que tu codes d'habitude, mais là, franchement c'est très facile...

  12. #52
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Je réflechis ! Mais je ne vois vraiment pas !
    Tu as un début de réponse dans le post 41...

    Thierry
    "The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
    "If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

    FAQ-Python FAQ-C FAQ-C++

    +

  13. #53
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Merci (désolé pour l'attente, je viens de reprendre le lycée [et la prog n'est plus ma priorité mais c'est mes études ] ) alors dans le post 41 je vois mon code ainsi que cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (s_message != NULL)
    {
       /* SUite du code */
    }
    Or dans la nouvelle version de mon code j'ai cette ligne, donc je me demande bien ce que vous voulez ?!

    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
     
    void pause(const char *s_message)
    {
        char c[2];
        if(s_message!=NULL)
        {
                            if (strlen(s_message)!=0)
                            {
                                                     fprintf(stdout, "%s", s_message);
                            }
        fflush(stdin); //If I write “stdout”, s_message is not visible !
        fgets(c, sizeof c, stdin);
        fclean(c, stdin);
        }
    }

  14. #54
    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 _SamSoft_ Voir le message
    Or dans la nouvelle version de mon code j'ai cette ligne, donc je me demande bien ce que vous voulez ?!
    A ma connaissance, c'est la première fois que tu publies cette version. Alors les remarques dans le genre "donc je me demande bien ce que vous voulez ?!", tu te les garde...

    Quand à ça,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
        fflush(stdin); //If I write “stdout”, s_message is not visible !
    C'est n'importe quoi. et il faut le retirer.

    Par contre, j'insiste,
    est indispensable ici.

    Je recommande ceci
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
     
    void fclean (char *s_buffer, FILE * stream)
    {
       if (s_buffer != NULL && stream != NULL)
       {
          char *pc = strchr (s_buffer, '\n');
     
          if (pc != NULL)           /* La saisie n'a pas été tronquée */
          {
             /* On remplace '\n' par le caractère nul '\0' */
             *pc = 0;
          }
          else
          {
             /* La saisie a été tronquée, on purge le flux d'entrée */
             int c;
             while ((c = fgetc (stream)) != '\n' && c != EOF)
             {
                continue;
             }
          }
       }
    }
     
    void pause (const char *s_message)
    {
       if (s_message != NULL && strlen (s_message) != 0)
       {
          fprintf (stdout, "%s", s_message);
          fflush (stdout);          //If I write “stdout”, s_message is not visible !
       }
       {
          char c[2];
          fgets (c, sizeof c, stdin);
          fclean (c, stdin);
       }
    }
     
    int main (void)
    {
       pause (NULL);
       pause ("");
       pause ("Appuyer sur une touche pour continuer");
       return 0;
    }
    selon les consignes publiées ici :

    http://www.developpez.net/forums/sho...6&postcount=36

    et que tu as du mal à suivre visiblement...

  15. #55
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Je m'excuse Je vais voir votre code.

    PS: Pour fflush, je continu de le dire, chez moi si je met fflush(stdout); je vois pas le contenu de s_message à l'écran !

  16. #56
    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 _SamSoft_ Voir le message
    Je m'excuse Je vais voir votre code.

    PS: Pour fflush, je continu de le dire, chez moi si je met fflush(stdout); je vois pas le contenu de s_message à l'écran !
    C'est pas possible. Tu as essayé avec mon code ? Tu dois obtenir ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
     
     
    Appuyer sur une touche pour continuer
    (2 pauses 'muettes' et une pause 'bavarde').
    • Quel est ton système ?
    • Quel est ton environnement de développement ?

  17. #57
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Merci pour votre code (plus lisible que le miens )

    Mais je crois que vous avez oublié un else :

    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
     
    void pause (const char *s_message)
    {
       if (s_message != NULL && strlen (s_message) != 0)
       {
          fprintf (stdout, "%s", s_message);
          fflush (stdout);          //If I write “stdout”, s_message is not visible !
       }
    /* Here */
       {
          char c[2];
          fgets (c, sizeof c, stdin);
          fclean (c, stdin);
       }
    }
    Sinon toujours rien (même après une reconstruction) sauf si je met fflush(stdin);

    Windows Vista Home Premium (achetté il y a 2mois)
    J'utilise DevCpp 4.9.9.2

  18. #58
    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 _SamSoft_ Voir le message
    Merci pour votre code (plus lisible que le miens )

    Mais je crois que vous avez oublié un else :
    Non.
    Sinon toujours rien (même après une reconstruction) sauf si je met fflush(stdin);

    Windows Vista Home Premium (achetté il y a 2mois)
    J'utilise DevCpp 4.9.9.2
    OK.

    Tu peux faire un copié-collé de l'écran de sortie ? (click droit etc.)

  19. #59
    Membre éclairé Avatar de _SamSoft_
    Profil pro
    Étudiant
    Inscrit en
    Février 2007
    Messages
    798
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2007
    Messages : 798
    Par défaut
    Entendu.

    Je ne comprend pas, vous voulez que je fasse un copier-coller ? A quoi cela sert-il ? De plus si je met stdout ca se passe comme ceci:


    Avec fgets
    str=
    montexte
    /me presse entrer
    str2=
    montexte
    /me presse entrer
    str=str2
    Appuyez sur une touche pour continuer...
    /me presse entrer
    Efface Ecran
    avec scanf
    str=
    montexte
    /me presse entrer
    str2=
    montexte
    /me presse entrer
    /prog Fermeture
    Avec stdin dans fflush j'ai (lors du deuxième exemple):

    avec scanf
    str=
    montexte
    /me presse entrer
    str2=
    montexte
    /me presse entrer
    Appuyez sur une touche pour continuer...
    /me presse entrer
    /prog Fermeture

  20. #60
    Expert confirmé
    Avatar de Skyounet
    Homme Profil pro
    Software Engineer
    Inscrit en
    Mars 2005
    Messages
    6 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 6 380
    Par défaut
    Citation Envoyé par _SamSoft_ Voir le message
    Mais je crois que vous avez oublié un else :
    En fait il a juste déclaré un nouveau bloc pour faire un petit traitement du coup dans ce bloc on peut déclarer de nouvelles variables valable juste dans ce bloc, c'est assez pratique.

    Je plussoie, fflush(stdin) ne fait rien (sauf sous Windows ), fflush(stdout) permet de vider le buffer de sortie, donc ce n'est pas un fflush(stdout) qui empeche s_message de s'afficher.

Discussions similaires

  1. fgets + scanf et gestion des espaces
    Par Yunchi dans le forum Débuter
    Réponses: 7
    Dernier message: 02/03/2009, 15h35
  2. Scanf, fgets et buffer.
    Par SAKDOSS dans le forum Bibliothèque standard
    Réponses: 6
    Dernier message: 15/01/2008, 08h58
  3. PB avec scanf
    Par ché dans le forum C
    Réponses: 6
    Dernier message: 13/08/2003, 07h25
  4. [debutant]la fonction scanf
    Par kalaka dans le forum C
    Réponses: 7
    Dernier message: 01/07/2003, 15h15
  5. Réponses: 6
    Dernier message: 10/09/2002, 03h35

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