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).
Re: c'est bon j'ai trouvé
Citation:
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"?
Re: c'est bon j'ai trouvé
Citation:
Envoyé par lestat
Citation:
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
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 :
- getchar()
- getc(stdin)
- fgetc(stdin)
- scanf()
- gets()
- fgets(,,stdin)
Les fonction 1 à 3 retirent un caractère de stdin. selon cet algorithme (à des nuances près selon le système)
Code:
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:
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:
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.
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.