OVH Cloud OVH Cloud

saisie clavier et fgets

5 réponses
Avatar
bibou
Bonjours,

voulant recuperer la saisie clavier, j'utilise fgets.
Mais je veux limiter la saisie a un certain nb de caracteres.
J'ai créé une fonction get_saisie qui rempli un buffer avec fgets.
Quand j'affichant le buffer la limite (taille du buffer) n'est pas prise
en compte et le reste de la chaine saisie au clavier est affiché.

J'ai bien compris que fgets lit un flux jusqu'a la fin (survenu de \n ou
\0). Donc ce comportement n'est pas supprenant.

Ce que je ne comprends pas c'est le mécanisme qui fait que le reste de la
chaine est afficher. Il y a un pointeur vers le reste de la chaine dans le
buffer ? j'affiche une chaine de 10 caracteres, comment fgets fait pour
renvoyer le reste ? le buffer a bien une taille de 10 mais si la saisie
fait 30 caracteres j'ai trois affichages de 10 pour un seul appel de
fonction....?????

pouvez vous m'expliquer ?

Merci
sebastien


code:
---------------------------------------------------------------

void get_saisie ( char * buffer, size_t taille) {
char* result = fgets(buffer, taille, stdin);

if (result != NULL) {
char* nl = strchr(buffer, '\n');

if (nl != NULL)
*nl = '\0';
}
}

int main (){

while (1){
char buffer [MAXSIZE];

get_saisie (buffer, MAXSIZE);
printf ("saisie = %s\n", buffer);
}
}

5 réponses

Avatar
Richard Delorme
Bonjours,

voulant recuperer la saisie clavier, j'utilise fgets.
Mais je veux limiter la saisie a un certain nb de caracteres.
J'ai créé une fonction get_saisie qui rempli un buffer avec fgets.
Quand j'affichant le buffer la limite (taille du buffer) n'est pas prise
en compte et le reste de la chaine saisie au clavier est affiché.

J'ai bien compris que fgets lit un flux jusqu'a la fin (survenu de n ou
). Donc ce comportement n'est pas supprenant.

Ce que je ne comprends pas c'est le mécanisme qui fait que le reste de la
chaine est afficher. Il y a un pointeur vers le reste de la chaine dans le
buffer ? j'affiche une chaine de 10 caracteres, comment fgets fait pour
renvoyer le reste ? le buffer a bien une taille de 10 mais si la saisie
fait 30 caracteres j'ai trois affichages de 10 pour un seul appel de
fonction....?????

pouvez vous m'expliquer ?


Ce qui n'est pas lu la première fois est lu les fois suivantes. C'est le
comportement normal de fgets(). Pour supprimer les caractères restant
sur la même ligne, voire la FAQ 14.5, où plutôt faire comme ça :

int c;

do {
c = getchar();
} while (c != EOF && c != 'n');

ou encore :
scanf("%*[^n]%*c");

--
Richard

Avatar
Emmanuel Delahaye
bibou wrote on 11/05/05 :
voulant recuperer la saisie clavier, j'utilise fgets.


BIen.

Mais je veux limiter la saisie a un certain nb de caracteres.


Alors fgets() peut convenir si il est bien utilisé.

J'ai créé une fonction get_saisie qui rempli un buffer avec fgets.


get + saisie, ça fait peut être beaucoup, non ?

Quand j'affiche le buffer la limite (taille du buffer) n'est pas prise
en compte et le reste de la chaine saisie au clavier est affiché.

J'ai bien compris que fgets lit un flux jusqu'a la fin (survenu de n ou
). Donc ce comportement n'est pas supprenant.


Non n uniquement, pas . Mais dans un flux 'texte' il ne devrait pas
y avoir de 0...

Ce que je ne comprends pas c'est le mécanisme qui fait que le reste de la
chaine est afficher. Il y a un pointeur vers le reste de la chaine dans le
buffer ? j'affiche une chaine de 10 caracteres, comment fgets fait pour
renvoyer le reste ? le buffer a bien une taille de 10 mais si la saisie
fait 30 caracteres j'ai trois affichages de 10 pour un seul appel de
fonction....?????


Doit y avoir une boucle quelque part...

Si tu veux que les caractères non lus soient éliminés, il faut les ...
éliminer !




code:
---------------------------------------------------------------

void get_saisie ( char * buffer, size_t taille) {
char* result = fgets(buffer, taille, stdin);

if (result != NULL) {
char* nl = strchr(buffer, 'n');

if (nl != NULL)
*nl = '';
}


C'est là qu'il manque le nettoyage.

/*
http://mapage.noos.fr/emdel/notes.htm#fichiers
*/

else
{
/* Le traitement depend de l'application.
* Par exemple, ici, on choisi d'ignorer
* les autres caracteres.
*/

/* sinon, on lit tous les caracteres restants */
int c;

while ((c = fgetc(fp)) != 'n' && c != EOF)
{
}
}

}

int main (){

while (1){


Tient, la boucle!

char buffer [MAXSIZE];

get_saisie (buffer, MAXSIZE);


get_saisie (buffer, sizeof buffer);


printf ("saisie = %sn", buffer);


Euh, on sort comment ?

}
}


--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

.sig under repair

Avatar
bibou
Le Thu, 12 May 2005 00:19:51 +0200, Emmanuel Delahaye a écrit :

bibou wrote on 11/05/05 :
Ce que je ne comprends pas c'est le mécanisme qui fait que le reste de la
chaine est afficher. Il y a un pointeur vers le reste de la chaine dans le
buffer ? j'affiche une chaine de 10 caracteres, comment fgets fait pour
renvoyer le reste ? le buffer a bien une taille de 10 mais si la saisie
fait 30 caracteres j'ai trois affichages de 10 pour un seul appel de
fonction....?????


Doit y avoir une boucle quelque part...


Evidemment ... j'suis cretin
Au second passage fgets renvoie le reste de la chaine.
Desolé de cette question idiote et merci d'y avoir repondu qu'en meme


Si tu veux que les caractères non lus soient éliminés, il faut les ...
éliminer !

oui ca c'est ok (merci pour le code)


sebastien


Avatar
Antoine Leca
En <news:,
bibou va escriure:
Ce que je ne comprends pas c'est le mécanisme qui fait que le reste
de la chaine est afficher.


Cela dépend de ton système d'exploitation (pas de la bibliothèque C).

Dans le mode normal, le système demande au pilote clavier une ligne entière
avant de la passer au programme; de cette manière, l'utilisateur peut
corriger ce qu'il saisit (les fautes de frappe bêtes, en particulier). C'est
seulement quand l'utilisateur appuie sur la touche Entrée que le système
commence à bosser pour de vrai et passe les caractères reçus à ton programme
(via fgets() et tout ce qu'il y a en-dessous). Évidemment, TOUT apparaît à
l'écran quand tu appuies sur Entrée, ce qui est transmis à fgets(), comme ce
qui reste prêt à être transmis à l'appel suivant de fgets().

Il existe d'autres modes, en particulier un autre où le système ne fait
aucune interprétation des touches pressées et les passe aussi vite qu'elles
arrivent au programme. Mais dans ce cas-là, tu dois interpréter toi-même les
corrections... En général c'est adapté pour une interface utilisateur plein
écran, ou un choix dans un menu, mais beuacoup moins pour saisir une ligne
de commande où on préfère nettement laissé à l'utilisateur la possibilité de
corriger les fautes de frappe.

Sous Unix, le mode normal est conventionnellement appelé "cooked", cuisiné,
et le mode sans interprétation "raw", brut.


Pour compliquer, il existe un autre axe de différences, celui d'avoir ou pas
écho à l'écran de ce qui est tapé au clavier. En général (mais ce n'est pas
une obligation), dans le mode normal il y a écho (ce qui permet à
l'utilisateur de voir ce qu'il fait et donc de corriger), et dans le mode
sans interprétation on supprime l'écho (et supposant que c'est le programme
qui gère l'interface utilisateur donc qui crée la retro-action). Mais ce
n'est pas réellement une obligation, les autres combinaisons sont parfois
possibles, ceci dépendant de plus des systèmes d'exploitation.


Antoine

Avatar
bibou
Le Thu, 12 May 2005 10:22:45 +0200, Antoine Leca a écrit :

En <news:,
bibou va escriure:
Ce que je ne comprends pas c'est le mécanisme qui fait que le reste
de la chaine est afficher.


Cela dépend de ton système d'exploitation (pas de la bibliothèque C).

Dans le mode normal, le système demande au pilote clavier une ligne entière
avant de la passer au programme; de cette manière, l'utilisateur peut
corriger ce qu'il saisit (les fautes de frappe bêtes, en particulier). C'est
seulement quand l'utilisateur appuie sur la touche Entrée que le système
commence à bosser pour de vrai et passe les caractères reçus à ton programme
(via fgets() et tout ce qu'il y a en-dessous). Évidemment, TOUT apparaît à
l'écran quand tu appuies sur Entrée, ce qui est transmis à fgets(), comme ce
qui reste prêt à être transmis à l'appel suivant de fgets().

Il existe d'autres modes, en particulier un autre où le système ne fait
aucune interprétation des touches pressées et les passe aussi vite qu'elles
arrivent au programme. Mais dans ce cas-là, tu dois interpréter toi-même les
corrections... En général c'est adapté pour une interface utilisateur plein
écran, ou un choix dans un menu, mais beuacoup moins pour saisir une ligne
de commande où on préfère nettement laissé à l'utilisateur la possibilité de
corriger les fautes de frappe.

Sous Unix, le mode normal est conventionnellement appelé "cooked", cuisiné,
et le mode sans interprétation "raw", brut.


Pour compliquer, il existe un autre axe de différences, celui d'avoir ou pas
écho à l'écran de ce qui est tapé au clavier. En général (mais ce n'est pas
une obligation), dans le mode normal il y a écho (ce qui permet à
l'utilisateur de voir ce qu'il fait et donc de corriger), et dans le mode
sans interprétation on supprime l'écho (et supposant que c'est le programme
qui gère l'interface utilisateur donc qui crée la retro-action). Mais ce
n'est pas réellement une obligation, les autres combinaisons sont parfois
possibles, ceci dépendant de plus des systèmes d'exploitation.


Antoine


merci de ces precisions Antoine.

Sebastien