Incompréhension EOF ET NULL

Incompréhension EOF ET NULL - C - Programmation

Marsh Posté le 19-04-2010 à 23:01:43    

Bonsoir a tous ;)
 
Pourquoi la boucle s'arrête quand fgetc renvoie EOF et quand fgets renvoie NULL ?
 

Code :
  1. while (fgets(chaine, TAILLE_MAX, fichier) != NULL)


 

Code :
  1. do
  2.         {
  3.             caractereActuel = fgetc(fichier); // On lit le caractère
  4.             printf("%c", caractereActuel); // On l'affiche
  5.         } while (caractereActuel != EOF);


 
 
La fonction fgets() va lire une ligne jusqu'à rencontrer \n et en mettant != NULL cela sera un boucle infini ? Non? ... car le pointeur retourné par fgets est toujours (!= NULL)  
 
En fin je suis perdu là..  :cry:


Message édité par lassault1 le 19-04-2010 à 23:31:25
Reply

Marsh Posté le 19-04-2010 à 23:01:43   

Reply

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

Quelle boucle?
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 à 23:14:23    

Je me permets juste de te conseiller un bouquin : "Le Langage C", de Kernighan & Ritchie. Clair et concis, je pense que ça t'aidera énormément avec toutes les questions que tu te poses.

Reply

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

J'ai édité..

Reply

Marsh Posté le 20-04-2010 à 02:09:13    

Citation :

while (fgets(chaine, TAILLE_MAX, fichier) != NULL)

Quand fgets renvoie NULL, le test de la boucle while devient while (NULL != NULL) comme (NULL != NULL) est faux, la boucle while s'arrête.

 
Citation :

  do
           {
               caractereActuel = fgetc(fichier); // On lit le caractère
               printf("%c", caractereActuel); // On l'affiche
           } while (caractereActuel != EOF);

quand fgetc recupere EOF, caractereActuel prend la valeur EOF, le test de la boucle while devient while (NULL != NULL) comme (NULL != NULL) est faux, la boucle while s'arrête.

 

Pourquoi fgets retourne NULL et fgetc retourne EOF? pour rester cohérent avec leur type de retour déclaré: fgets retourne un pointeur, donc on va retourner une valeur compatible avec ce type: NULL, et fgetc retourne un int, donc on va retourner une valeur compatible avec ce type: EOF.

 

A+,


Message édité par gilou le 20-04-2010 à 08:11:13

---------------
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 à 13:05:32    

Merci..
 
Je crois que pour vraiment comprendre je dois savoir ça :
 
1/ Est ce que le fonction fgets renvoie un pointeur juste pour vérifier si la lecture a bien été faite et aussi pour nous permettre de faire des boucles en faisant while fgets(...) != NULL ?
 
2/ Si la fonction fgets ne renvoyait pas de pointeur (chaine) est-ce qu'on aurait pu lire la chaine dans le printf ou est-ce qu'il faut qu'il nous renvoie la chaine pour pouvoir la lire?
 
3/ Avez vous les fonctions fgets et fgetc pour voir leur fonctionnement?

Reply

Marsh Posté le 20-04-2010 à 15:35:23    

Citation :

1/ Est ce que le fonction fgets renvoie un pointeur juste pour vérifier si la lecture a bien été faite et aussi pour nous permettre de faire des boucles en faisant while fgets(...) != NULL ?

grosso modo oui, mais on peut aussi utiliser le pointeur si l'on veut:
chaine = fgets(...);
if (chaine) {
 longueur = strlen(chaine);
 ...
}
 
2) C'est quoi cette histoire de printf? quel est le rapport avec la choucroute.
 
3) non, c'est peut être écrit en assembleur ou autre chose, je n'en sais rien et n'ai pas besoin de le savoir pour programmer en C
 
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 à 18:42:35    

Merci mais je vais  reformulé ma question :
 
Pourquoi quand on envoie a la fonction fgets() l'adresse du tableau chaine en paramètre elle a besoin de renvoyer le pointeur (ici l'adresse de chaine) car je pensé qu'elle pouvait modifier (remplir) le tableau chaine directement en mémoire et pas besoin de le renvoyer??
 
Autre question j'ai n'ai beaucoup je sais :p
 
Pourquoi dans ce code la fonction strlen() calcule que la longueur de la dernière ligne et non tout le contenu de mon tableau ?
 

Code :
  1. #define TAILLE_MAX 1000
  2. int main(int argc, char *argv[])
  3. {
  4.     FILE* fichier = NULL;
  5.     char chaine[TAILLE_MAX] = "";
  6.     fichier = fopen("test.txt", "r" );
  7.     if (fichier != NULL)
  8.     {
  9.         while(fgets(chaine, TAILLE_MAX, fichier) != NULL)
  10.      {
  11.         printf("%s\n", chaine);
  12.      }
  13.         printf("Longueur de chaine est : %d\n", strlen(chaine));
  14.         fclose(fichier);
  15.     }
  16.     return 0;
  17. }


 

Reply

Marsh Posté le 20-04-2010 à 19:01:38    

Citation :

Pourquoi quand on envoie a la fonction fgets() l'adresse du tableau chaine en paramètre elle a besoin de renvoyer le pointeur (ici l'adresse de chaine) car je pensé qu'elle pouvait modifier (remplir) le tableau chaine directement en mémoire et pas besoin de le renvoyer??

C'est ce que je t'ai expliqué l'autre fois:
Si ce que tu passes en paramètre est un tableau, ca vaudra jamais NULL, donc pour signaler que la fonction a échoué, il faudrait renvoyer un code d'erreur etc. et les inventeurs du langage C voulaient introduire le minimum de tels codes possible dans la librairie commune.
En renvoyant un pointeur mis a NULL si ca a échoué, on fait d'une pierre deux coups.
 

Citation :

Pourquoi dans ce code la fonction strlen() calcule que la longueur de la dernière ligne et non tout le contenu de mon tableau ?

strlen, c'est une fonction de chaine C, donc ca s'occupe de chercher le \0 qui doit terminer la chaine (pour elle la chaine s'arrête la, même si il y a des choses ensuite dans la tableau).
Elle calcule donc la longueur de la ligne.
Pourquoi c'est la dernière ligne?
Parce que a chaque tour du while, la ligne lue écrase la ligne précédente (qui était copiée dans le tableau), et que ton printf est apres le while.
Si tu veux que ca t'affiche la longueur de chaque ligne, faut mettre ton printf dans la boucle du while.
Et si tu veux la longueur totale, il faut un entier mis a zéro, dans lequel tu ajoute la longueur de chaque ligne a chaque boucle du while.
 
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 à 19:56:40    

lassault1 a écrit :


3/ Avez vous les fonctions fgets et fgetc pour voir leur fonctionnement?

gilou a écrit :

3) non, c'est peut être écrit en assembleur ou autre chose, je n'en sais rien et n'ai pas besoin de le savoir pour programmer en C



Tu peux peut-être arriver à la trouver dans les sources de la librairie standard. Mais comme gilou l'a dit, mis à part essayer de briller en récitant à qui veut l'entendre le source de fgets() lors de soirées "branchées", ça ne te servira pas à grand chose...


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

Marsh Posté le 20-04-2010 à 19:56:40   

Reply

Marsh Posté le 20-04-2010 à 21:02:33    

Si dans mon fichier je met :
 

Citation :


Bonjour
Salut


 
Alors pourquoi quand on fait une boucle while la 1ere ligne n'est pas écrasé par la 2eme dans la console  :
 
La console affichera :
 

Citation :


Bonjour
Salut


 
et non :
 

Citation :


Salut


Message édité par lassault1 le 20-04-2010 à 21:25:43
Reply

Marsh Posté le 20-04-2010 à 22:09:20    

Parce que c'est dans la boucle du while que tu as: printf("%s\n", chaine);
C'est exécuté avant chaque écrasement successif, donc ca affichera chaque ligne sur la console avant qu'elle soit écrasée par la suivante.
Mais par contre ton printf("Longueur de chaine est : %d\n", strlen(chaine)); est lui après la boucle du while, et donc il n'est executé que pour la dernière ligne.
A+,


Message édité par gilou le 20-04-2010 à 22:09:49

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

Marsh Posté le 21-04-2010 à 00:05:17    

En conclusion, si je mets dans mon fichier :
 
Bonsoir
Toto

 
Et que je fais une boucle alors la console affichera
 
Bonsoir
Toto

 
Mais mon tableau contiendra que Toto en mémoire ??  
 
C'est ça ?

Reply

Marsh Posté le 21-04-2010 à 02:55:47    

Il contiendra la première fois Bonsoir, puis ca sera effacé, et il contiendra Toto (pour être plus juste, il contiendra "Bonsoir\n\0", puis il contiendra "Toto\n\0r\n\0". Mais les fonctions qui travaillent sur les chaines se moquent de ce qui suit le premier \0, alors tu vois pas ce qui est après [pour le voir, il faut regarder ses données comme un tableau, et parcourir case a case])
Bon je suis plus la jusqu'à vendredi.
A+,


Message édité par gilou le 21-04-2010 à 02:57:05

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

Sujets relatifs:

Leave a Replay

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