Pouvez vous m'expliquer? - C - Programmation
Marsh Posté le 19-04-2010 à 13:25:30
1. Pourquoi vouloir un "entier qui nous place à la position 0" ? Cela suffit de vouloir revenir à la postion 0. D'ailleurs, peut-être qu'au lieu de rewind(), vous voudriez fseek() ou ftell().
2. Oui, Salut\0\0 fait 7 caractères de long, mais il n'est pas dit qu'il ne faut réserver que 6 octets.
Marsh Posté le 19-04-2010 à 13:36:40
Citation : Comment récupérer l'entier qui nous place à la position 0 dans le fichier si ce prototype renvoie rien? |
Il a rien a renvoyer, puisqu'après l'avoir exécuté, tu es à la position zéro.
Mais si ça te chante, tu peux toujours faire:
rewind(fichier);
position = ftell(fichier);
A+,
Marsh Posté le 19-04-2010 à 14:32:25
Merci..
Pour la 1ere question c'est ok..
Pour la 2eme il est dit pour ce code :
Code :
|
Citation : La fonction fgets étant sécurisée, elle s'est arrêtée de lire au bout du 9ème caractère, car nous avions alloué un tableau de 10 char (il ne faut pas oublier le caractère de fin de chaîne \0 qui occupe la 10ème position). |
Mais pourquoi il dit que la fonction fgets s'est arrêtée de lire au bout du 9ème caractère, car ce que j'ai compris c'est que fgets s'arrête au 8ème caractère, le 9ème étant "\n" et la 10ème "\0" ??
Marsh Posté le 19-04-2010 à 14:49:35
"\n" est un caractère, qui n'est pas alphabètique, mais qui est un caractère quand même. Par ailleurs, '\0' est parfois appelé le caractère nul, et d'ailleurs, l'auteur l'appelle le "caractère de fin de chaine". Donc je pense comme vous, que l'auteur s'est trompé, mais qu'il aurait dû dire que fets() a lu 10 caractères, au lieu de 9 ou 8.
Marsh Posté le 19-04-2010 à 16:47:11
Merci olivthill
On m'a dit : parque le "\n" se trouve a la fin de Jean Edouard Albert 1er car on a appuyé sur la touche entré et non a la fin de Jean Edou..
Marsh Posté le 19-04-2010 à 19:55:03
lassault1 a écrit : On m'a dit : parque le "\n" se trouve a la fin de Jean Edouard Albert 1er car on a appuyé sur la touche entré et non a la fin de Jean Edou.. |
C'est exact.
D'ailleurs, dans l'absolu, un fichier qui contient
toto
titi
tata
contient en réalité toto\ntiti\ntata\n. C'est ton éditeur qui reconnait le "\n" et qui transforme cet amas de caractères en un beau fichier bien propre avec 3 lignes à l'écran.
Marsh Posté le 19-04-2010 à 20:33:08
ReplyMarsh Posté le 19-04-2010 à 20:37:16
lassault1 a écrit : Donc qui dit vrai olivthill (qui était de mon avis) ou ce qu'on m'a dit? |
Ben on a tous dit vrai !!!
Nos propos individuels ne sont pas en désaccords les uns des autres
Toutefois, t'as dit un truc qui me gène:
Citation : car ce que j'ai compris c'est que fgets s'arrête au 8ème caractère, le 9ème étant "\n" et la 10ème "\0" ?? |
Là c'est pas bon. Le 9° caractère n'est absolument pas "\n" car c'est le "u". Il n'y a aucune raison que fgets() aille ajouter un "\n" là où il n'y en a pas...
Marsh Posté le 19-04-2010 à 21:57:31
Pourtant il a dit que l'auteur s'est trompé...
Bref le "\n" se trouve a la fin de Jean Edouard Albert 1er car on a appuyé sur la touche entré et non a la fin de Jean Edou ??
Marsh Posté le 19-04-2010 à 23:19:15
lassault1 a écrit : Merci.. Pour la 1ere question c'est ok..
Mais pourquoi il dit que la fonction fgets s'est arrêtée de lire au bout du 9ème caractère, car ce que j'ai compris c'est que fgets s'arrête au 8ème caractère, le 9ème étant "\n" et la 10ème "\0" ?? |
Non:
Tu as la chaine "Jean Edouard Albert 1er\n" qui a été tapée par l'utilisateur et est dans le buffer clavier.
fgets(..., 10, clavier) ca lit 10-1 = 9 caractères sur le buffer clavier, donc ca lit "Jean Edou", ca rajoute un zero a la fin, donc on a ""Jean Edou\0" et ca te renvoie cette chaine (qui est une bonne chaine pour le C, puisqu'elle est maintenant bien terminée par un \0)
Si tu appelais a nouveau lire, fgets lirait 9 caractères du reste: "ard Alber", et ajouterait un \0 a la fin, et te renverrait la chaine ""ard Alber\0".
Si tu appelais a nouveau lire, fgets essaie de lire 9 caractères du reste, mais comme il n'y a que 6 caractères dans le reste: "t 1er\n", fgets lit les caractères, et quand il trouve \n, il arrête de lire et renvoie la chaine trouvée, en ajoutant après le \n un \0. Il renvoie donc "t 1er\n\0"
Si tu appelais a nouveau lire, comme il n'y a plus rien a lire, fgets va renvoyer NULL
A+,
Marsh Posté le 20-04-2010 à 00:36:22
gilou a écrit : mais comme il n'y a que 6 caractères dans le reste: "t 1er\n", fgets lit les caractères, et quand il trouve \n, il arrête de lire et renvoie la chaine chaine trouvée, en ajoutant après le \n un \0. Il renvoie donc "t 1er\n\0" |
C'est parfait ! j'ai compris..
Mais juste que je croyais qu'il renvoie "t 1er\0\0"
Exemple :
t 1er\n\0 ---> Avant l'appel de la fonction strchr
t 1er\0\0 ---> Après l'appel de la fonction strchr (pour remplacer \n par \0)
Je me trompe ??
Marsh Posté le 20-04-2010 à 02:03:24
Si c'est de fgets que tu parles, quand fgets va rencontrer "t 1er\n\0", quand \n va être attteint, fgets ne va pas plus loin et renvoie "t 1er\n\0"
c'est quoi cette histoire de strchr? tu réimplémentes fgets?
A+,
Marsh Posté le 20-04-2010 à 12:21:11
strchr c'est la fonction qui permet de chercher un caractere dans une chaine
Voici le code entier :
Code :
|
Donc je pense que c'est :
t 1er\n\0 ---> Avant l'appel de la fonction strchr
t 1er\0\0 ---> Après l'appel de la fonction strchr (pour remplacer \n par \0) ??
Marsh Posté le 20-04-2010 à 14:13:29
Quand on appuie sur la touche Entrée, cela produit un '\n'. Quand il y a un saut de ligne dans un fichier, il y a un '\n'.
S'il n'y a ni touche entrée, ni saut de ligne, alors fgets() ne vas pas inventer un nouveau '\n'. Par contre fgets() va créer un '\0' en fin de chaine.
fgets() va lire les caractères jusqu'à la longueur maximale qui est spécifiée, ou jusqu'au premier '\n' qui est rencontré.
Généralement, on n'a pas besoin du '\n' qui se trouve à la fin d'une ligne ou d'une saisie qui s'est terminée par un appui sur la touche entrée. Donc, souvent, on remplace le '\n' par un '\0'. C'est ce qui se passe dans ce programme.
N.B. Ce programme n'est pas optimisé. strchr() fait une recherche en partant de la gauche, alors que l'on sait que le '\n' se trouvera à droite (sauf si la lecture est tronquée à cause la longueur maximale qui a été atteinte). Donc, au lieu du strchr(), il est plus efficace d'avoir une petite boucle en partant de la droite pour tester le '\n' et le remplacer par un '\0'.
Marsh Posté le 20-04-2010 à 14:34:21
olivthill a écrit : N.B. Ce programme n'est pas optimisé. strchr() fait une recherche en partant de la gauche, alors que l'on sait que le '\n' se trouvera à droite (sauf si la lecture est tronquée à cause la longueur maximale qui a été atteinte). Donc, au lieu du strchr(), il est plus efficace d'avoir une petite boucle en partant de la droite pour tester le '\n' et le remplacer par un '\0'. |
Comment tu trouves la droite? En faisant une boucle qui cherche le premier \0 a partir de la gauche?
Marsh Posté le 20-04-2010 à 15:00:18
olivthill a écrit : fgets() va lire les caractères jusqu'à la longueur maximale qui est spécifiée, ou jusqu'au premier '\n' qui est rencontré. |
la longueur maximale spécifiée moins 1, pour qu'il y ait la place d'ajouter le '\0' final.
A+,
Marsh Posté le 20-04-2010 à 15:02:38
En conclusion a la fin de la chaine il y aura bien 2 "\0\0"
je veux juste savoir si c'est oui ou non ?
Marsh Posté le 20-04-2010 à 15:17:33
Dans ton tableau, oui (et pas a la fin, la ou l'entree s'arrete). Une chaine par definition s'arrete au premier \0 et ce qui suit (dans ce cas un deuxieme \0) n'en fait pas partie.
Marsh Posté le 20-04-2010 à 15:19:37
lassault1 a écrit : Donc je pense que c'est : t 1er\n\0 ---> Avant l'appel de la fonction strchr |
Non et non!
Le buffer clavier, il y a aucune raison qu'il contienne autre chose que ce que tu as tapé. Donc si tu tapes t 1er[Retour Chariot]
Le buffer clavier il va contenir "t 1er\n" et rien d'autre a priori. Pas de '\0' derrière le '\n'. Un buffer clavier, c'est une zone ou il y a des caractères les uns derrière les autres, mais rien ne dit que c'est une chaine C et que sa se termine par un '\0' (C'est peut être la cas, ou pas, seul les codeurs système de la machinerie logicielle (driver) qui sait récupérer ce que tu as tapé au clavier pour le mettre dans un buffer le savent, toi, tu n'as pas a t'en préoccuper).
Et getc ou fgets, ca remplace rien dans le buffer clavier! ca vide le buffer clavier, et ca en copie le contenu. Ca utilise pas strchr.
getc ca copie le contenu dans sa valeur de sortie, et fgets ca copie le contenu dans la zone pointée par le pointeur que tu lui as passé.
Si j'ai "t 1er\n" dans le buffer clavier.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par 't' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui ci contient maintenant " 1er\n".
getc retourne la valeur copiée, 't'.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par ' ' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui ci contient maintenant "1er\n".
getc retourne la valeur copiée, ' '.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par '1' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui ci contient maintenant "er\n".
getc retourne la valeur copiée, '1'.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par 'e' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui ci contient maintenant "r\n".
getc retourne la valeur copiée, 'e'.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par 'r' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui ci contient maintenant "\n".
getc retourne la valeur copiée, 'r'.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer commence par '\n' getc copie cette valeur pour le retourner.
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui modifie le buffer clavier, celui est maintenant vide.
getc retourne la valeur copiée, '\n'.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer est vide (ou qui lui retourne la valeur EOF).
getc retourne la valeur EOF.
** Appel a getc:
getc appelle quelque chose (tu sais pas quoi, ca dépend de l'OS...) qui lui dit que le buffer est vide (ou qui lui retourne la valeur EOF).
getc retourne la valeur EOF.
etc
A+,
Marsh Posté le 20-04-2010 à 15:53:24
gilou pourquoi non?
Quand fgets copie Jean Edouard Albert 1er\n dans ma chaine j'aurais bien ça Jean Edouard Albert 1er\n\0 après on cherche \n avec strchr() et on remplace \n par \0 ce qui fait Jean Edouard Albert 1er\0\0...
Ou est l'erreur ?
Marsh Posté le 20-04-2010 à 16:09:39
Il suffit de lire le man, par exemple : http://www.linux-kheops.com/doc/ma [...] 3.txt.html
Citation : fgets() lit au plus size - 1 caractères depuis stream et |
Donc, fgets(chaine, longueur, stdin), en plus de la copie du buffer, ajoute un '\0'.
Par contre, fgetc() qui n'ajoute pas de '\0', mais c'est un autre sujet.
strchr() est évoqué car il fait partie du programme qui a été montré.
Citation : Comment tu trouves la droite? En faisant une boucle qui cherche le premier \0 a partir de la gauche? |
Tu as raison cher Un Programmeur. Je vois que dans mes programme, j'utilise strlen() donc, je pars aussi depuis la gauche, et j'ai dit des betises, sorry.
lg = strlen(s); |
Marsh Posté le 20-04-2010 à 16:29:41
lassault1 a écrit : gilou pourquoi non? Quand fgets copie Jean Edouard Albert 1er\n dans ma chaine j'aurais bien ça Jean Edouard Albert 1er\n\0 après on cherche \n avec strchr() et on remplace \n par \0 ce qui fait Jean Edouard Albert 1er\0\0... Ou est l'erreur ? |
Mea Culpa, j'avais pas vu ton nouveau code, j'en etais resté à l'état d'hier.
Oui, c'est ça:
fgets copie Jean "Edouard Albert 1er\n" et ajoute '\0' pour te faire une vraie chaine C
Quand fgets retourne, ton buffer contient "Edouard Albert 1er\n\0"
Tu auras bien dans le tableau chaine "Jean Edouard Albert 1er\0\0" après le remplacement, quand strchr aura trouvé '\n'.
Notes que pour faire la même chose, tu peux aussi utiliser strlen plutot que strchr.
Incidemment, j'avais écrit un truc faux à la fin de mon 2e post hier (probablement pas les idées claires a cause de la fièvre, je suis sous antibios). J'ai corrigé cela.
A+,
Marsh Posté le 20-04-2010 à 18:13:24
Ok merci c'est résolu..
Ps : c'est quoi l'erreur que tu as dit car je me rappel plus?
Marsh Posté le 20-04-2010 à 18:49:13
J'avais pas mis les \n dans ce que retournait fgets
A+,
Marsh Posté le 19-04-2010 à 13:19:41
Bonjour a tous
1/ Comment récupérer l'entier qui nous place à la position 0 dans le fichier si ce prototype renvoie rien?
2/
Citation d'un totorial :
Ce schéma montre que la chaîne écrite par fgets était "Mateo\n\0". Nous avons remplacé le \n par un \0, ce qui a donné au final : "Mateo\0\0".
Ce n'est pas grave d'avoir deux \0 d'affilée. L'ordinateur s'arrête au premier \0 qu'il rencontre et considère que la chaîne de caractères s'arrête là.
Il y a un problème dans ce qu'il dit car si j'alloue un tableau de 6 char et j'entre le mot "Salut" alors il y aura "Salut\n\o" et même si je remplace \n par \0 j'aurais "Salut\0\0" donc débordement ? :?