Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

comprendre fgets

94 réponses
Avatar
bpascal123
Bonjour

Avec p2 qui pointe sur une chaine saisie avec fgets (ex."abcd")
dans for ( p2 ; *p2 ; p2++ )
Pourquoi l'incr=E9mentation se fait sur 6 intervalles en m=E9moire.

0 =3D a
1 =3D b
2 =3D c
3 =3D d
4 =3D \0
5 =3D ???

A quoi correspond la derni=E8re position (numero 5) ?

(En fait, je veux dire que je dois d=E9cr=E9menter 2 fois apres la fin
de la boucle for pour pointer p2 sur 'd' en position 3). Ca veut dire
qu'en plus de '\0', fgets inclue un autre caract=E8re.

Question suppl=E9mentaire (culture g=E9n=E9ral en informatique) :
La chaine enregistr=E9e avec fgets se trouve dans la memoire ram ou
dans un des registres?

Merci

10 réponses

6 7 8 9 10
Avatar
-ed-
On 21 nov, 20:50, ""
wrote:
Bonjour/bonsoir,

Est-ce que fgets a un comportement différent selon l'OS (Djgpp
Microsoft xp ou Linux Gcc) ? Parce que sous Windows le pointeur se
trouve 1 position supplémentaire après la fin de la chaîne saisie a vec
fgets ce qui va en contradiction avec le premier post (peut-être j'ai
écrit le premier post sous linux et c'est pourquoi aujourd'hui je ne
me retrouve qu'une position après au lieu de 2.



Mais quel pointeur ?

Si quelqu'un peut m'aider. J'ai le sentiment de passer beaucoup de
temps sur point particulier qui ne devrait pas avoir d'importance pour
un débutant car à un niveau plus élevé, la saisie se fait de mani ère
très rigoureuse avec flush ou getchar =''n' ....



Tout est là :

http://www.bien-programmer.fr/notes.php#saisie
Avatar
candide
-ed- a écrit :

Tout est là :




Et on se demande comment il y en a encore qui posent des questions sur
le C ...


http://www.bien-programmer.fr/notes.php#saisie




Langage C ou langage de bois ? Petit extrait :


"Saisie de données par un opérateur (stdin)"
"acquérir des données en provenance d'un opérateur"
"ce qui n'est évidemment pas le cas avec un opérateur humain"

Non mais t'as appris le C en corée du Nord ou quoi ?


Autres extraits de notre Monsieur Jourdain du C :

"Mode conversationnel" ?????????????? Ça me fait irrésistiblement penser
aux "commodités de la conversation " :))


"stdin est connecté à la partie 'clavier' d'un périphérique console"
J'ai une question m'sieur : où c'est qu'il est le port usb de vo't stdin
siouplait ?


"C'est insuffisant pour saisir autre chose qu'un simple <ENTER>."

Ah bon ? getchar() ne peut saisir que <ENTER> ? K&R ne savent donc pas
utiliser getchar().


"S'il faut saisir une valeur numérique, celle-ci sera d'abord saisie
sous forme de ligne, puis traduite par la fonction appropriée (strtol(),
strtoul(), strtod()) ou sscanf()) avec le filtre approprié : "

Ah ouais, il te faut 37 lignes de code pour saisir un malheureux entier
? Tu cherches à dégoûter les gens d'apprendre le C ? ou à faire croire
que t'es très très fort ?


Tiens, justement, regardons ton code :

//-------------------------------------
char temp[20];

do
{
char saisie[20];

/* Et quelques pédanteries plus loin, on lit ceci : */


ret = sscanf (saisie, "%[0-9-]s", temp);
//-------------------------------------


N'as-tu pas appris que sscanf() avec %s ajoute automatiquement un zéro à
la fin et donc que temp doit avoir au moins une case de plus que saisie ?

Et ton scanlist 0-9, il est portable ? Mon compilateur ne dit rien mais
la Norme dit :

If a - character is in the scanlist and is not the first, nor the second
where the first character is a ^, nor the last character, the behavior is
implementation-defined.
Avatar
bpascal123
On 22 nov, 01:42, Samuel Devulder
wrote:
a écrit :

> Si quelqu'un peut m'aider. J'ai le sentiment de passer beaucoup de
> temps sur point particulier qui ne devrait pas avoir d'importance pour
> un débutant car à un niveau plus élevé, la saisie se fait de ma nière
> très rigoureuse avec flush ou getchar =''n' ....

Tu t'es laissé noyé dans les querelles un peu vaines de spécialiste s qui
  on fait dériver le fil loin, très loin, de ton pb initial. Si tu
pouvais (re)poster l'essentiel du code pour qu'on rappelle correctement
ton histoire de -1 / -2? Parce que selon moi ton pb est simple et la
solution avait été donnée très tot dans le fil: buffer contenant
"abcdn" et donc d est à l'offset -2 par rapport à la position du ' '.

sam.



Bonjour,bsr,

Il s'agit de ce post plus haut dans cette discussion :
int main(void)
{
char Ch[101] ;
char *p1, *p2 ;
int Pali ;
p2 = Ch ;
printf("nEntrez une ligne de texte (max.100 caract.) :
n") ;
fgets(Ch, 101, stdin) ;
for ( p2 ; *p2 ; p2++ )
;
p2 = p2-2 ;
...

Avec windows, pour un autre exercice, je me suis retrouvé avec une
situation identique mais avec un résultat différent en ce sens que
p2-1 ou p2-- au lieu de p2=p2-2.

Il s'agit peut-être d'une confusion.

Pascal
Avatar
espie
In article ,
wrote:
Il s'agit de ce post plus haut dans cette discussion :
int main(void)
{
char Ch[101] ;
char *p1, *p2 ;
int Pali ;
p2 = Ch ;
printf("nEntrez une ligne de texte (max.100 caract.) :
n") ;
fgets(Ch, 101, stdin) ;


Deja, fgets renvoie un resultat. Il faut le tester. Si fgets te renvoie
NULL, alors ton tableau contiendra n'importe quoi.

for ( p2 ; *p2 ; p2++ )
;
p2 = p2-2 ;


Cette ligne est fausse. Si on appuie directement sur entree, le tampon
contiendra seulement un caractere: tu te retrouves avec p2 qui vaut
&(Ch[-1]). Tu es dans le domaine du comportement indefini...


Commence par corriger tout ca, on en reparle ensuite...
Avatar
Richard Delorme
Le 21/11/2009 20:50, a écrit :
Bonjour/bonsoir,

Est-ce que fgets a un comportement différent selon l'OS (Djgpp
Microsoft xp ou Linux Gcc) ? Parce que sous Windows le pointeur se
trouve 1 position supplémentaire après la fin de la chaîne saisie avec
fgets ce qui va en contradiction avec le premier post (peut-être j'ai
écrit le premier post sous linux et c'est pourquoi aujourd'hui je ne
me retrouve qu'une position après au lieu de 2.

Si quelqu'un peut m'aider. J'ai le sentiment de passer beaucoup de
temps sur point particulier qui ne devrait pas avoir d'importance pour
un débutant car à un niveau plus élevé, la saisie se fait de manière
très rigoureuse avec flush ou getchar =''n'



C'est normal, sous certains OS, dont ceux de Microsoft, la fin de ligne
contient deux caractères ("nr" ou le contraire) au lien d'un seul
("n") sous Unix.
Quelque soit l'OS, si s est un pointeur vers le dernier caractère non
nul de la chaine, il suffit de vérifier son contenu pour effacer les
caractères de fin de ligne :

while (*s == 'n' || *s == 'r') {
*s-- = '';
}

--
Richard
Avatar
espie
In article <4b0bc93b$0$993$,
Richard Delorme wrote:
Le 21/11/2009 20:50, a écrit :
Bonjour/bonsoir,

Est-ce que fgets a un comportement différent selon l'OS (Djgpp
Microsoft xp ou Linux Gcc) ? Parce que sous Windows le pointeur se
trouve 1 position supplémentaire après la fin de la chaîne saisie avec
fgets ce qui va en contradiction avec le premier post (peut-être j'ai
écrit le premier post sous linux et c'est pourquoi aujourd'hui je ne
me retrouve qu'une position après au lieu de 2.

Si quelqu'un peut m'aider. J'ai le sentiment de passer beaucoup de
temps sur point particulier qui ne devrait pas avoir d'importance pour
un débutant car à un niveau plus élevé, la saisie se fait de manière
très rigoureuse avec flush ou getchar =''n'



C'est normal, sous certains OS, dont ceux de Microsoft, la fin de ligne
contient deux caractères ("nr" ou le contraire) au lien d'un seul
("n") sous Unix.



Euh non, ce que tu decris, c'est une implementation "non conforme" ou du
moins qui a decide de ne pas implementer la distinction flux binaire/flux
texte.

D'apres 7.19.2, sur un flux texte, le systeme peut convertir les choses
pour que la lecture te montre un 'n' pour une fin de ligne.

D'apres 7.19.3.7, stdin, stdout et stderr sont des flux textes.

Si tu es sur une implementation qui distingue effectivement entre fopen "t"
et fopen "b", ben c'est ni plus ni moins qu'un bug.


(de facon assez drole, il *n'existe pas de facon standard* d'obtenir un flux
binaire qui correspond a stdin. De facon encore plus drole, d'apres 7.19.2.2,
il y a tres peu d'implementations standard dans la nature... c'est frequent
d'avoir des espaces avant le 'n', par exemple).
Avatar
Richard Delorme
Le 24/11/2009 15:47, Marc Espie a écrit :

C'est normal, sous certains OS, dont ceux de Microsoft, la fin de ligne
contient deux caractères ("nr" ou le contraire) au lien d'un seul
("n") sous Unix.



Euh non, ce que tu decris, c'est une implementation "non conforme" ou du
moins qui a decide de ne pas implementer la distinction flux binaire/flux
texte.



Tous les Unix sont donc non conformes ?

D'apres 7.19.2, sur un flux texte, le systeme peut convertir les choses
pour que la lecture te montre un 'n' pour une fin de ligne.

D'apres 7.19.3.7, stdin, stdout et stderr sont des flux textes.

Si tu es sur une implementation qui distingue effectivement entre fopen "t"
et fopen "b", ben c'est ni plus ni moins qu'un bug.



Sauf que si le fichier vient d'un système conforme qui "peut convertir
les choses" et est lu sur un système conforme qui ne convertit rien ou
d'une autre manière, il n'y a pas de bug dans l'implémentation mais des
problèmes de lecture quand même.

--
Richard
Avatar
Jean-Marc Bourguet
(Marc Espie) writes:

De facon encore plus drole, d'apres 7.19.2.2, il y a tres peu
d'implementations standard dans la nature... c'est frequent d'avoir des
espaces avant le 'n', par exemple).



Quel probleme y a-t'il?

Whether space characters that are written out immediately before a new-line character
appear when read in is implementation-defined.


Ma comprehension est qu'un programme strictement conforme ne peut pas
dependre du fait qu'ils soient conserves, mais rien n'empeche une
implementation d'en supprimer, de conserver exactement ceux qui existent ou
d'en ajouter. (Je m'attends plutot aux deux premieres eventualites).

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Avatar
Antoine Leca
Pascal écrivit :
Est-ce que fgets a un comportement différent selon l'OS (Djgpp
Microsoft xp ou Linux Gcc) ?



Non.

Parce que sous Windows le pointeur se
trouve 1 position supplémentaire après la fin de la chaîne saisie



Huh ? Peux-tu préciser le compilateur utilisé et les options de
compilations, s'il te plaît.


Antoine
Avatar
Antoine Leca
Richard Delorme écrivit :
C'est normal, sous certains OS, dont ceux de Microsoft, la fin de ligne
contient deux caractères ("nr" ou le contraire) au lien d'un seul
("n") sous Unix.



Euh, elle ne devrait pas (vu du programme, évidemment ; vu de
l'extérieur, c'est "1512").
Si c'est le cas, c'est probablement que tu utilises des options de
compilations (comme ajouter binmode.o[bj]) qui éloigne ton
implémentation de la norme (mais permettent de porter plus facilement
certains utilitaires issus d'Unix où les programmeurs fainéants ont omis
de mettre "rb", "r+b" ou "wb" pour les chaînes de mode d'ouverture des
fichiers contenant des flux binaires).


Quelque soit l'OS, si s est un pointeur vers le dernier caractère non
nul de la chaine, il suffit de vérifier son contenu pour effacer les
caractères de fin de ligne :

while (*s == 'n' || *s == 'r') {
*s-- = '';
}



Oui ; même si c'est inutile au vu de la norme, c'est en effet une
manière solide de faire.


Antoine
6 7 8 9 10