Bonjour
L'entrée http://www.developpez.com/faq/?page=...buffer_clavier me pose problème car elle considère qu'il y a quelque dans le buffer. Quand il est vide, on attend !
Bonjour
L'entrée http://www.developpez.com/faq/?page=...buffer_clavier me pose problème car elle considère qu'il y a quelque dans le buffer. Quand il est vide, on attend !
Modérateur Mageia/Mandriva Linux
Amicalement VOOotre
Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
Mes tutoriels : xrandr, algorigramme et C, xml et gtk...
Lien correct
En fait, la réponse est simple: Il n'existe rien en standard pour "vider le buffer clavier".
L'entrée de la FAQ sert à "finir de lire la ligne courante" (après un scanf() ou après un fgets() n'ayant pas retourné de \n).
C'est généralement suffisant tant que tu restes en Command-Line Interface.
Si par contre tu veux une interface qui n'attend pas [Entrée] (et que tu utilises donc getch()) tu peux faire une simple boucle while(kbhit()) getch(); pour vider le buffer clavier.
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.
Ce problème a déjà été abordé ici : http://www.developpez.net/forums/d76...s/#post6685910
Je viens de regarder les différentes archives...
Pour rendre ce programme compatible avec plus de compilateurs C, il faudrait initialiser les variables au début de la fonction.
Et surtout, il faudrait un peu expliquer ! C'est beau de piquer un programme, mais il faut le comprendre !
Modérateur Mageia/Mandriva Linux
Amicalement VOOotre
Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
Mes tutoriels : xrandr, algorigramme et C, xml et gtk...
En gros, ça fait la même chose que le while(kbhit()) getch();, à bas niveau, et par blocs de 64 bytes.
Et c'est pour POSIX uniquement.
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.
Bonjour,
Euh, elles le sont. De quelles variables non initialisées parles-tu ?
Et surtout, il faudrait un peu expliquer ! C'est beau de piquer un programme, mais il faut le comprendre !
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 #ifndef _POSIX_SOURCE #define _POSIX_SOURCE #endif #include <errno.h> #include <stdio.h> #include <fcntl.h> /* Vide le buffer d'entrée d'un flux utilisable * en lecture. Renvoie 1 en cas d'échec, 0 sinon. */ int fclearbuf (FILE * f) { int ret = 1; int fd = -1; /* Si f est NULL ou si le descripteur est invalide, sors directement. */ if (f!=NULL) if ((fd=fileno(f))>=0) { long flags = 0; /* Récupère les flags associés au flux */ flags = (long)fcntl (fd,F_GETFL,0); /* Sors également si le flux n'est pas utilisable en lecture */ if (!(flags & O_WRONLY)) { char buffer [64]; /* Ajoute le flag non bloquant aux attributs actuels */ fcntl (fd,F_SETFL,flags | O_NONBLOCK); /* Lis un bloc et continue tant que l'on arrive à en */ /* obtenir un entier et que, donc, il a potentiellement */ /* des données restantes derrière. */ while (fread(buffer,sizeof buffer,1,f)==1); /* Si on s'est arrêté à cause d'une erreur et que */ /* cette erreur est EWOULDBLOCK en particulier */ /* alors c'est celle que l'on attendait et on la réinitialise. */ /* Sinon, on laisse le programme appelant la gérer. */ if (ferror(f) && errno == EWOULDBLOCK) { clearerr (f); ret = 0; } /* Remets les flags dans l'état où on les a trouvés en entrant, et sors. */ fcntl (fd,F_SETFL,flags); } } return ret; }
Le buffer a une longueur de 64 octets, choisie complètement arbitrairement. L'idée était d'éviter de faire un appel système par caractère, tout en économisant la pile et en choisissant une taille en rapport avec la quantité de caractères en attente et saisie au clavier, puisque c'est généralement à cela que sert cette fonction.
Par contre, je m'aperçois que j'ai omis de gérer la valeur de retour de fcntl() qui peut échouer pour bon nombre de raisons et ça, c'est une lacune ! Désolé.
C'est surtout utile là où kbhit() n'est pas disponible, et c'est à bas niveau parce qu'effectivement, puisqu'il n'y a rien d'exploitable dans la norme C, ça devient de la programmation système.
Ensuite, « bas niveau », oui et non parce que ça reste un fread(), mais il faut bien positionner le flag anti-bloquant d'une façon ou d'une autre.
Oui, c'est comme cela qu'on l'a présenté (dans le post initial en tous cas).Et c'est pour POSIX uniquement.
Je parlais des variables flag et buffer qui ne sont pas initialisées en début de procédure, mais plus loin. Toutes les normes de C, surtout les plus anciennes, ne tolèrent pas ça.
Merci pour tes explications. Il me restera à comprendre certaines notions que je n'ai pas encore comme fcntl.
Je pourrai l'utiliser en le comprenant !
Modérateur Mageia/Mandriva Linux
Amicalement VOOotre
Troumad Alias Bernard SIAUD à découvrir sur http://troumad.org
Mes tutoriels : xrandr, algorigramme et C, xml et gtk...
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.
Partager