Pouvez vous m'expliquer?

Pouvez vous m'expliquer? - C - Programmation

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?
 

Code :
  1. void rewind(FILE* pointeurSurFichier);


 
2/

Citation :

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 ?  :??: :?

Reply

Marsh Posté le 19-04-2010 à 13:19:41   

Reply

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.

Reply

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+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 :
  1. int main(int argc, char *argv[])
  2. {
  3.     char nom[10];
  4.     printf("Quel est votre nom ? " );
  5.     lire(nom, 10);
  6.     printf("Ah ! Vous vous appelez donc %s !\n\n", nom);
  7.     return 0;
  8. }


 

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).
Le problème, c'est que le reste de la chaîne qui n'a pas pu être lu, à savoir "ard Alber 1er", n'a pas disparu ! Il est toujours dans le buffer.

Résultat:
Quel est votre nom ? Jean Edouard Albert 1er
Ah ! Vous vous appelez donc Jean Edou !


 
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" ??  
 

Reply

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.

Reply

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..

Reply

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.


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 19-04-2010 à 20:33:08    

Donc qui dit vrai olivthill (qui était de mon avis) ou ce qu'on m'a dit?

Reply

Marsh 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...


Message édité par Sve@r le 19-04-2010 à 20:51:15

---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

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 ??

Reply

Marsh Posté le 19-04-2010 à 21:57:31   

Reply

Marsh Posté le 19-04-2010 à 23:19:15    

lassault1 a écrit :

Merci..

 

Pour la 1ere question c'est ok..

 


Pour la 2eme il est dit pour ce code :

 
Code :
  1. int main(int argc, char *argv[])
  2. {
  3.     char nom[10];
  4.     printf("Quel est votre nom ? " );
  5.     lire(nom, 10);
  6.     printf("Ah ! Vous vous appelez donc %s !\n\n", nom);
  7.     return 0;
  8. }
 
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).
Le problème, c'est que le reste de la chaîne qui n'a pas pu être lu, à savoir "ard Alber 1er", n'a pas disparu ! Il est toujours dans le buffer.

Résultat:
Quel est votre nom ? Jean Edouard Albert 1er
Ah ! Vous vous appelez donc Jean Edou !

 

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+,

Message cité 1 fois
Message édité par gilou le 20-04-2010 à 16:45:29

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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"
A+,

 

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 ??


Message édité par gilou le 20-04-2010 à 16:46:45
Reply

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+,


Message édité par gilou le 20-04-2010 à 16:47:26

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 :
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. int lire(char *chaine, int longueur);
  4. void viderBuffer();
  5. int main(int argc, char *argv[])
  6. {
  7.     char nom[10];
  8.     printf("Quel est votre nom ? " );
  9.     lire(nom, 10);
  10.     printf("Ah ! Vous vous appelez donc %s !\n\n", nom);
  11.     lire(nom, 10);
  12.     printf("Ah ! Vous vous appelez donc %s !\n\n", nom);
  13.     return 0;
  14. }
  15. int lire(char *chaine, int longueur)
  16. {
  17.     char *positionEntree = NULL;
  18.     if (fgets(chaine, longueur, stdin) != NULL)
  19.     {
  20.         positionEntree = strchr(chaine, '\n');
  21.         if (positionEntree != NULL)
  22.         {
  23.             *positionEntree = '\0';
  24.         }
  25.         else
  26.         {
  27.             viderBuffer();
  28.         }
  29.         return 1;
  30.     }
  31.     else
  32.     {
  33.         viderBuffer();
  34.         return 0;
  35.     }
  36. }
  37. void viderBuffer()
  38. {
  39.     int c = 0;
  40.     while (c != '\n' && c != EOF)
  41.     {
  42.         c = getchar();
  43.     }
  44. }


 
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)  ?? :??:

Message cité 1 fois
Message édité par lassault1 le 20-04-2010 à 12:22:25
Reply

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'.

Reply

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?  ;)


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

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+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 ?

Reply

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.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

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
 
t 1er\0\0  ---> Après l'appel de la fonction strchr (pour remplacer \n par \0)  ?? :??:

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+,


Message édité par gilou le 20-04-2010 à 15:28:02

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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 ?

Reply

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
       les place  dans  le  buffer  pointé  par  s.   La  lecture
       s'arrête  après  EOF  ou  un retour-chariot. Si un retour-
       chariot (newline) est lu, il est placé dans le buffer.  Un
       caractère nul '\0' est placé à la fin de la ligne.


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);
   while (lg > 0 && s[lg - 1] <= ' ')
      s[--lg] = '\0';

Reply

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+,

 



Message édité par gilou le 20-04-2010 à 16:44:51

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

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?
 

Reply

Marsh Posté le 20-04-2010 à 18:49:13    

J'avais pas mis les \n dans ce que retournait fgets
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed