Comprendre l'usage de STDIN ???
salmamk27
Messages postés
3
Date d'inscription
Statut
Membre
Dernière intervention
-
salmamk27 Messages postés 3 Date d'inscription Statut Membre Dernière intervention -
salmamk27 Messages postés 3 Date d'inscription Statut Membre Dernière intervention -
Bien bonjour !
je viens de commencer les fichiers et j'ai trouvé un mot que je n'est pas colpris l'usage qui est :
STDIN ???
je viens de commencer les fichiers et j'ai trouvé un mot que je n'est pas colpris l'usage qui est :
printf("input a sentence for the file :");
fgets(str,sizeof str,stdin);
fprintf(fptr,"%s",str);
printf("the file (filesalma.txt) is created ");
STDIN ???
1 réponse
-
Bonjour salmamk27,
fgets()
est une fonction définie dans l'entête standardstdio.h
et dont le prototype est le suivant :
char * fgets ( char * str, int num, FILE * stream );
cf. http://www.cplusplus.com/reference/cstdio/fgets/
Son 3ème argument est un pointeur surFILE
permettant d'accéder à un flux de lecture.
Puisque tu dis que étudies les fichiers, tu dois savoir qu'un tel pointeur surFILE
sur un flux de lecture peut être défini par l'ouverture d'un fichier avecfopen()
en lecture.
De fait, tu peux, bien sûr, utiliserfgets()
pour lire le contenu disponible dans un fichier.
Mais tu peux aussi passer àfgets()
le pointeur surFILE
"stdin" qui est définit parstdio.h
.
La norme du C prévoit questdin
est un pointeur sur FILE permettant d'accéder au flux de l'entrée standard (que tu n'as pas à ouvrir avecfopen()
, car il est déjà disponible selon le standard du C, et que tu ne devrais pas fermer avecfclose()
).
http://www.cplusplus.com/reference/cstdio/stdin/?kw=stdin
Ce flux de l'entrée standard est, normalement, le flux des caractères entrés au clavier (cela peut être aussi un flux redirigé ayant une autre origine), mis en tampon par le système et qui est accessible par cette fonctionfgets()
si tu lui passesstdin
en 3ème argument. Le même fluxstdin
est accédé par d'autres fonctions définies parstdio.h
conçues pour lire ce flux seulement (commescanf()
ougetchar()
, qui ne nécessitent pas que tu précises le flux, car elles n'opèrent que sur l'entrée standard).
Ici,stdin
se comporte exactement comme le flux d'un fichier ouvert en lecture.
Utilisée pour lire des informations provenant d'une saisie par l'utilisateur au clavier, la fonctionfgets()
a cet avantage qu'il est facile au programme de limiter la lecture du flux à un nombre maximal dechar
à lire, pour ne pas dépasser la capacité de l'espace mémoire utilisé pour stocker ce qui est lu : dans ton cas l'emplacement pointé parstr
. La lecture du flux est donc limitée à ce qui figure en 2ème argument (sizeof str
la fonction prenant en compte le caractère terminateur'\0'
qui est ajouté).
C'est une façon recommandée d'éviter les risques de débordement de tampon et de corruption de la mémoire, qui peut occasionner des plantages, comportements imprévisibles ou des problèmes de sécurité, en ignorant leschar
saisis en plus qui dépasseraient la capacité de stockage indiquée y compris le caractère terminateur.
Cette limitation du nombre dechar
lus sur le flux d'entrée standard est également possible avecscanf()
, en utilisant les spécificateurs de taille de cette fonction, mais cette façon de faire est moins naturelle et peut être omise par les programmeurs inattentifs.
Par exemple :
char str[50] = { '\0' }; printf("Veuillez taper 49 caractères au plus\n"); if (scanf("%49[^\n]", str) == 1) { printf("J'ai récupéré : [%s]\n", str); }
Tu dois déduire toi même de la taille disponible l'espace nécessaire au caractère terminateur'\0'
ajouté parscanf()
.
Il y a d'autres différences et subtilités, concernant ces fonctions mais je m'arrêterai là pour le moment :-)
Il y a aussi d'autres flux standard définis par le C :- le flux de sortie standard (écran du terminal normalement, sauf redirection) :
stdout
(là où va le résultat de printf() par exemple) - le flux (de sortie) d'erreur standard (idem) :
stderr
(là où va le résultat de perror() par exemple)
Voir :
http://www.cplusplus.com/reference/cstdio/stdout/
http://www.cplusplus.com/reference/cstdio/stderr/
Dal-
-
Oui, c'est vrai que cet oubli est très fréquent.
Dans l'enseignement initial du C il peut même être volontaire par l'enseignant, pour utiliser intentionnellementscanf()
de façon simplifiée avec"%s"
(un peu comme un pendant "naturel" àprintf()
avec ce qui semble être le même"%s"
), pour gérer une entrée au clavier sans considérations de robustesse ou de sécurisation du code à ce stade pour ne pas "embrouiller" les personnes débutantes.
La réalité est quescanf()
est une des fonctions les plus délicates à (bien) utiliser du langage C... il n'y a qu'à voir la taille de la page de manuel de cette fonction.
Elle est quand même pratique lorsqu'elle est bien utilisée...
Comme tu le sais,fgets()
pour gérerstdin
a ses propres problèmes ou contraintes : possible inclusion du retour chariot'\n'
avant le caractère terminateur (si la taille de la saisie le permet), supposant un retraitement de la chaîne obtenue au clavier, si ce retour chariot est indésirable... d'un autre côtéscanf()
ne prend pas le retour chariot, qui reste dansstdin
...
@salmamk27 : on peut en dire plus sur ces aspects, car tu ne fais qu'entrevoir la partie immergée de l'iceberg. Les deux fonctions nécessitent d'être attentifs au contenu obtenu et à celui restant dans le tamponstdin
, non consommé parscanf()
oufgets()
qui peut être différent, si on ne veut pas se retrouver avec des surprises selon les opérations suivantes de lecture destdin
à réaliser.
Il est aussi déconseillé de mélanger l'usage des deux fonctions, compte tenu de leurs comportements différents. -
- le flux de sortie standard (écran du terminal normalement, sauf redirection) :