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 :

fflush(stdin)


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 4
    Par défaut fflush(stdin)
    voila....;j'ai essayé de remplacer le fflush mais ca ne fonctionne qu'a moitié....alors, je vais demander si j'envoie mon code a quelqu'un, pourrait-il regarder a corriger pour les getchar() et scanf() afin de pouvoir vider le buffer clavier parce qu'a mon avis j'utilise mal le getchar...en fait je ne comprend pas quand on doit vider ou non le buffer clavier et aussi avant l'entree ou apres l'entree...enfin soit sinon le programme tourne...manque encore des fonctions et le bug du getchar m'énerve

  2. #2
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 4
    Par défaut c'est bon j'ai trouvé
    je crois avoir compris....ca a l'aire de fonctionner...cela etant dit, si qq'un peut m'expliquer quand est-ce important de vider le buffer clavier ca serait gentil......

  3. #3
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut Re: c'est bon j'ai trouvé
    Citation Envoyé par lestat
    je crois avoir compris....ca a l'aire de fonctionner...cela etant dit, si qq'un peut m'expliquer quand est-ce important de vider le buffer clavier ca serait gentil......
    A chaque fois qu'il reste des caracteres dans ce buffer, c'est a dire suite au saisie via getchar, scanf, etc... qui n'ont pas commencer l'integralite de la saisie (tres souvent le \n final).

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 4
    Par défaut Re: c'est bon j'ai trouvé
    A chaque fois qu'il reste des caracteres dans ce buffer, c'est a dire suite au saisie via getchar, scanf, etc... qui n'ont pas commencer l'integralite de la saisie (tres souvent le \n final).
    c'est a dire:"n'ont pas commencé l'integralite"?

  5. #5
    Rédacteur

    Avatar de khayyam90
    Homme Profil pro
    Architecte de système d’information
    Inscrit en
    Janvier 2004
    Messages
    10 371
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Architecte de système d’information

    Informations forums :
    Inscription : Janvier 2004
    Messages : 10 371
    Par défaut
    bien le bonjour

    un vidage de buffer est nécessaire après un getchar ou un scanf ou toute autre fonction qui laisse trainer qqch dans le buffer. Sinon un getchar (par exemple) passera sans attendre que tu tapes qqch. le \n qui traine lui suffira.

  6. #6
    Membre émérite
    Profil pro
    Eleveur de cornichons
    Inscrit en
    Juin 2002
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Eleveur de cornichons
    Secteur : Finance

    Informations forums :
    Inscription : Juin 2002
    Messages : 1 074
    Par défaut
    Faut toujours vider le buffer, c'est mieux. Si quelque chose traine dans le buffer, il sera enlevé. S'il n'y a rien, on ne perd à rien à le faire.

    Quand peut-il y avoir des données qui trainent ?
    Par exemple, si ton scanf() est comme ceci :
    et que tu tapes : 15 13 56
    On a tapé ici 3 entiers alors que le scanf() n'en attendait que 2 !
    Conséquence : le 56 reste dans le buffer...
    La prochaine fois que t'appelle un scanf(), le 56 sera le premier élément.
    Par exemple si tu rappelles un scanf() ainsi :
    c'est le 56 qui est placé dans d.
    C'est une parmi d'autres raisons.

    Nas'

  7. #7
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut Re: c'est bon j'ai trouvé
    Citation Envoyé par lestat
    A chaque fois qu'il reste des caracteres dans ce buffer, c'est a dire suite au saisie via getchar, scanf, etc... qui n'ont pas commencer l'integralite de la saisie (tres souvent le \n final).
    c'est a dire:"n'ont pas commencé l'integralite"?
    oups !!! c'etait consomme que je voulais mettre, je suis vraiment pas reveille aujourd'hui

  8. #8
    Expert éminent

    Avatar de Anomaly
    Homme Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 380
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 380
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Nasky
    Faut toujours vider le buffer, c'est mieux. Si quelque chose traine dans le buffer, il sera enlevé. S'il n'y a rien, on ne perd à rien à le faire.
    Sauf que cela va empêcher de rediriger l'entrée (par exemple, pour automatiser l'appel d'un programme interactif dans un script).

  9. #9
    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 Re: c'est bon j'ai trouvé
    Citation Envoyé par lestat
    je crois avoir compris....ca a l'aire de fonctionner...cela etant dit, si qq'un peut m'expliquer quand est-ce important de vider le buffer clavier ca serait gentil......
    Le fonctions de lecture de stdin sont :
    1. getchar()
    2. getc(stdin)
    3. fgetc(stdin)
    4. scanf()
    5. gets()
    6. fgets(,,stdin)

    Les fonction 1 à 3 retirent un caractère de stdin. selon cet algorithme (à des nuances près selon le système)

    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
     
    SI aucun '\n' n'a été detecté
       Suspendre l'execution du programme
       SI une frappe du clavier autre que BACKSPACE ou ENTER est detectée, 
          Placer le caractère reçu dans stdin. 
          Faire un echo à la console.
       SINON SI c'est BACKSPACE (et que stdin n'est pas vide)
          Retirer le dernier caractère entré dans stdin
          Faire un écho destructif (BS SPC BS)
       SINON ; c'est donc 'ENTER'
          placer un '\n' dans stdin
          reprendre l'execution
       FIN SI
    FIN SI
    extraire le premier caractère de stdin
    retourner ce caractère
    On voit donc que tant qu'il reste des caractères dans stdin, l'appel aux fonctions de lecture n'est pas supensif.

    Petite expérience:

    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
     
    #include <stdio.h>
     
    int main (void)
    {
       int n = 0;
       int c;
     
       do
       { 
          c = getchar ();
          n++;
          printf ("[%d]%d\n", n, c);
       }
       while (c != '\n');
     
       printf ("%d caracteres lu%s\n", n, n > 1 ? "s" : "");
     
       return 0;
    }
    Maintenant, on execute le programme.

    On saisie les chiffres de 1 à 6
    Le programme répond:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    [1]49
    [2]50
    [3]51
    [4]52
    [5]53
    [6]54
    [7]10
    7 caracteres lus
    Les nombres 49 à 54 sont les valeurs ASCII des caractères '1' à '6'
    Le nombre 10 est la valeur ASCII de '\n'
    On voit bien que le programme ne reprend pas tant que l'utilisateur n'a pas tapé ENTER. (Par contre, il est possible de modifier la ligne : correction avec BACKSPACE, par exemple)

    Ensuite, on constate que getchar() est appelé 7 fois, jusqu'à ce que le caractère '\n' ait été lu. Pour lire stdin entièrement, il faut donc aller jusqu'au '\n'.

    Mise en situation
    On a souvent :
    Voulez vous continuer (Oui, Non) ?
    Et on tape
    oENTER

    On voit donc qu'on a fait rentrer 2 caractères dans stdin : 'o' et '\n'
    Si on se contente d'appeler une fois getchar(), on retire 'o'. Il reste '\n'. Si on appelle encore une fois getchar(), il n'y aura pas de suspension de l'exécution, et '\n' sera retourné.

    Conclusion, getchar() n'est pas la fonction qu'il faut pour lire un caractère.

    En fait, ce problème de '\n' pendant survient avec toutes les fonctions de lectures de stdin, sauf fgets() (et encore, il y a des cas).

    Utilisation détaillée de fgets().

    La lecture de la documentation de fgets() nous apprend que les paramètres de cette fonction sont :
    • char *buffer
    • size_t size
    • FILE *stream

    Le paramètre 'buffer' est l'adresse du tableau de char dans lequel fgets() va écrire les caractères extraits de stdin.
    Le paramètre 'size' est la taille en byte de ce tableau. Cette information est primordiale, car elle permet à fgets() d'éviter tout débordement.
    Le paramètre stream est l'adresse du flux lu (par exemple stdin, qui rappelons le, est un des trois flux ouverts par défaut en C)

    On peut donc appeler la fonction de la façon suivante :

    char buf[10];
    fgets (buf, sizeof buf, stdin);

    Comme avec getchar(), fgets() va suspendre l'exécution jusqu'à détection d'un '\n' (Touche ENTER, par exemple). Mais ensuite, et sous le contrôle du paramètre 'size', elle va automatiquement extraire les caractères qu'elle peut de stdin, et les placer dans le 'buffer', y compris le '\n'.

    La fonction fgets() est astreinte à une condition draconienne. Elle doit produire une chaine valide. Celà signifie que l'écriture dans 'buffer' (et par conséquend la lecture de stdin) s'arrétera toujours de façon à laisser de la place pour le 0 final, qui lui, sera toujours écrit par fgets().

    Celà signifie qu'il est des cas où le '\n' n'est pas lu, et qu'il reste donc 'pendant'. En aucun cas, le tableau de char 'buffer' ne peut déborder (sauf, si évidemment un farfelu à passé n'importe quelle valeur dans le paramètre size).

    Dans le cas où le '\n' est pendant, (donc absent de 'buffer'), on peut envisager plusieurs traitements, comme par exemple :
    • Eliminer les caractères pendants
    • Agrandir le buffer et continuer la lecture, jusqu'à avoir tout saisi.

  10. #10
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2004
    Messages : 4
    Par défaut bien merci a tous...je me sens tout de suite plus eclairé...
    c'est sérieux, je vous remercie tous...en tout cas..j'ai suivi les conseils...et mon programme n'a plus un bug....aller si peut etre a l'affichage mais la il n'y a rien de compliqué, ce sont juste des valeurs que je dois rentrer correctement....mais avec le getchar et scanf, je n'ai plus de problèmes....celui que ca interesse, je pourrai lui passer le code c'est une bataille navale...logiquement compatible a tout systeme d'exploitation encore que je ne l'ai pas testé partout mais je pense que sur linux il fonctionne et en borland en tout cas, il fonctionne.

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

Discussions similaires

  1. [FAQ] fflush(stdin) => Comment vider le buffer clavier ?
    Par troumad dans le forum Contribuez
    Réponses: 7
    Dernier message: 09/10/2013, 14h52
  2. [Debutant] fflush(stdin)
    Par liljip dans le forum C
    Réponses: 3
    Dernier message: 16/03/2007, 19h18
  3. fflush
    Par ggnore dans le forum C
    Réponses: 3
    Dernier message: 06/01/2005, 17h58
  4. fflush(stdin)
    Par BURZUM dans le forum C
    Réponses: 2
    Dernier message: 06/01/2004, 10h59
  5. descripteur stdin stdout
    Par discogarden dans le forum Réseau
    Réponses: 10
    Dernier message: 08/01/2003, 23h25

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