Lecture de fichier

Lecture de fichier - C - Programmation

Marsh Posté le 12-04-2006 à 13:19:28    

Je n'arrive pas lire dans un fichier texte avec cette fonction:
 

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      char lettre;
  4.      int i=0;
  5.    
  6.      while((lettre = (fgetc(fd))!= EOF))
  7.      {
  8.           buf[i] = lettre;
  9.           i++;
  10.      }
  11. }


 
Puis dans le main ():
 

Code :
  1. char buffer[1024];
  2. fd = fopen("log.txt", "r+" );               
  3. Read_File(fd, buffer);


 
Cette fonction Read_File() fait planter le programme.
Quelqu'un peut-il m'aider ?
 
 
 

Reply

Marsh Posté le 12-04-2006 à 13:19:28   

Reply

Marsh Posté le 12-04-2006 à 13:43:43    

Il est possible que le "r+" te positionne à la fin du fichier, fait un fseek(fd, SEEK_SET, 0l);
D'autre part tu ne vérifies pas le retour de fopen.
Enfin fgetc renvoie un int et donc lettre doit être du type int, tu fais ensuite un cast de lettre ne char.

Reply

Marsh Posté le 12-04-2006 à 13:44:07    

La fonction fgetc() renvoie un entier, pas un caractère, donc il faudrait déclarer int lettre;
 
Par ailleurs, personnellement, je n'utilise pas EOF mais feof(fp), mais ça revient peut-être au même.
 
Il faut aussi faire attention à ne pas oublier de compléter le buffer avec un caractère nul après la boucle while, dans le cas courant où l'on désire avoir une chaine de caractères normale.

Reply

Marsh Posté le 12-04-2006 à 13:52:31    

olivthill a écrit :

Par ailleurs, personnellement, je n'utilise pas EOF mais feof(fp), mais ça revient peut-être au même.
 
Il faut aussi faire attention à ne pas oublier de compléter le buffer avec un caractère nul après la boucle while, dans le cas courant où l'on désire avoir une chaine de caractères normale.

Non, feof n'est à utiliser qu'en cas de problème de lecture pour savoir si on est en fin de fichier ou si un problème de lecture est effectivement intervenu.
Par contre tu as tout à fait raison pour le 0 terminal.


Message édité par Trap D le 12-04-2006 à 13:53:27
Reply

Marsh Posté le 12-04-2006 à 13:55:07    

Merci pour l'info Trap D, et désolé d'avoir répondu en même temps pour le int au lieu du char.

Reply

Marsh Posté le 12-04-2006 à 14:13:23    

olivthill a écrit :

Merci pour l'info Trap D, et désolé d'avoir répondu en même temps pour le int au lieu du char.

Je suis plus rapide du clavier   :D  

Reply

Marsh Posté le 12-04-2006 à 16:51:54    

Mince, impossible d'ouvrir mon fichier avec fopen.
Comme indiqué je verifie fopen et le probleme semble venir de là . (merci)
 

Code :
  1. fd = fopen("log.txt", "r" );


 
Quand au '\0', la chaine en est remplie des le depart avec un memset.
Par ailleurs j'ai changé fgetc par un  
 

Code :
  1. fscanf(fd, "%s", buf[i])


 
Pourquoi je ne peux pas ouvrir ce Fichier ?

Message cité 1 fois
Message édité par Iscream le 12-04-2006 à 16:54:45
Reply

Marsh Posté le 12-04-2006 à 16:55:07    

#
    char lettre;
#
    int i=0;
#      
#
    while((lettre = (fgetc(fd))!= EOF))
 
 
lettre doit être de type int

Reply

Marsh Posté le 12-04-2006 à 16:56:51    

Iscream a écrit :

Mince, impossible d'ouvrir mon fichier avec fopen.
Pourquoi je ne peux pas ouvrir ce Fichier ?


  • Il n'existe pas
  • Il est déjà ouvert
  • ...


Essaye ça :  

Code :
  1. #include <stdio.h>
  2. #define fname "log.txt"
  3. int main (void)
  4. {
  5.    FILE *fp = fopen (fname, "r" );
  6.    if (fp != NULL)
  7.    {
  8.       /* ... */
  9.       fclose (fp), fp = NULL;
  10.    }
  11.    else
  12.    {
  13.       perror(fname);
  14.    }
  15.    return 0;
  16. }


et dis nous quel est le message ?


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 12-04-2006 à 16:58:24    

Code :
  1. FILE *f = fopen( "log.txt", "r" );
  2. if( f == NULL )
  3.   perror( "fopen" );

si ton fopen foire, avec ça tu sauras pourquoi ...
 
[EDIT] Emmanuel, tu as été plus rapide ... :D


Message édité par franceso le 12-04-2006 à 16:59:34

---------------
TriScale innov
Reply

Marsh Posté le 12-04-2006 à 16:58:24   

Reply

Marsh Posté le 12-04-2006 à 17:11:19    

merde quelle honte !
 
no such file or directory.
Mon fichier s'appelait log.txt.txt je suppose, renommé ca marche.
 
Merci, super pratique ce perror, faudra que je regarde ca plus souvent.

Reply

Marsh Posté le 12-04-2006 à 17:31:27    

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      int lettre;
  4.      int i=0;
  5.    
  6.      while((lettre = (fgetc(fd))!= EOF))
  7.         {
  8.              buf[i] = lettre;
  9.              i++;
  10.              MessageBoxA(NULL, buf, "MessageBoxA()", MB_OK);
  11.         }
  12. }


 
Dsl me voila de retour plus tot que prevu.
 
Lorsque j'appelle cette fonction elle remplie buf[i] a chaque fois avec la premiere lettre du fichier sans passer a la suivante.
Au final la boucle est infinie car elle reste au debut du fichier et buf
ressemble a : buf[] = "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"
r etant la premiere lettre du fichier.
 
Comment puis faire une fonction qui remplisse une variable avec le contenue d'un fichier correctement ???
 

Reply

Marsh Posté le 12-04-2006 à 17:41:00    

En général on fait avec fgets qui lit une ligne du fichier.

Reply

Marsh Posté le 12-04-2006 à 17:42:30    

Iscream a écrit :

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      int lettre;
  4.      int i=0;
  5.    
  6.      while((lettre = (fgetc(fd))!= EOF))
  7.         {
  8.              buf[i] = lettre;
  9.              i++;
  10.              MessageBoxA(NULL, buf, "MessageBoxA()", MB_OK);
  11.         }
  12. }




  • Comment est défini le buf de l'appelant ?
  • Pourquoi une MessageBox() ? Tu es sous GUI ? Pourquoi tu ne valides pas ton code en mode console, c'est nettement plus simple pour les traces...
  • Je suppose que MessageBoxA() attend une chaine de caractères valide. Tu penses que buf est une chaine valide ? Qui a mis le 0 final ?
  • Si tu veux lire un fichier txte, pourquoi tu ne le lis pas ligne à ligne avec fgets() ? C'est fait pour... GRILLAID


http://mapage.noos.fr/emdel/notes.htm#saisie
http://mapage.noos.fr/emdel/notes.htm#fichiers


Message édité par Emmanuel Delahaye le 12-04-2006 à 17:42:58

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 12-04-2006 à 18:47:49    

Emmanuel >> le P.O. nous a dit qu'il avait fait un memset avant l'appel, je suppose que c'est avec des 0.

Reply

Marsh Posté le 12-04-2006 à 19:20:12    

Read_File dans le meme genre que gets, c'est une faille de sécurité

Reply

Marsh Posté le 13-04-2006 à 20:31:55    

Iscream a écrit :

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      int lettre;
  4.      int i=0;
  5.    
  6.      while((lettre = (fgetc(fd))!= EOF))
  7.         {
  8.              buf[i] = lettre;
  9.              i++;
  10.              MessageBoxA(NULL, buf, "MessageBoxA()", MB_OK);
  11.         }
  12. }



 
On peut se passer de "i" et de "buf[i]" qui est "relativement" long

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      int lettre;
  4.      char *pt=buf;
  5.    
  6.      while((lettre = (fgetc(fd))!= EOF))
  7.      {
  8.              *pt= lettre;
  9.              pt++;
  10.       }
  11.      *pt=0;    // Ca évite même de remplir "buf" dans la fonction appelante
  12. }


 
Maintenant, ptet que ma question va sembler idiote... mais pourquoi ne pas utiliser "getline()" qui est faite pour ça ???


Message édité par Sve@r le 13-04-2006 à 20:33:43

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

Marsh Posté le 13-04-2006 à 20:45:46    

faudrais au moins passer la taille du tableau ! (surtout que le code appelant est lui meme assez vulnerable)
Sinon pour getline (celui de la glibc) c'est mieux mais ce n'est pas standard

Reply

Marsh Posté le 13-04-2006 à 22:21:15    

sinon t'as le droit de faire un fread hein ...

Reply

Marsh Posté le 14-04-2006 à 10:14:40    

Iscream a écrit :

Code :
  1. void Read_File(FILE* fd, char* buf)
  2. {
  3.      int lettre;
  4.      int i=0;
  5.    
  6.      while ((lettre = (fgetc(fd))!= EOF))
  7.         {
  8.              buf[i] = lettre;
  9.              i++;
  10.              MessageBoxA(NULL, buf, "MessageBoxA()", MB_OK);
  11.         }
  12. }


 
Dsl me voila de retour plus tot que prevu.
 
Lorsque j'appelle cette fonction elle remplie buf[i] a chaque fois avec la premiere lettre du fichier sans passer a la suivante.
Au final la boucle est infinie car elle reste au debut du fichier et buf
ressemble a : buf[] = "rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr"
r etant la premiere lettre du fichier.
 
Comment puis faire une fonction qui remplisse une variable avec le contenue d'un fichier correctement ???


 
Je suis désolé de répondre à une question par une autre question... mais as-tu réalisé que, ta fonction telle que tu la prépares, va stocker un fichier de taille inconnue dans une zone de 1024 octets ? T'es sûr que ça va tenir ???  :D  
 
Autre remarque que personne n'a vu jusqu'à présent (i'm the winner, désolé pour Emmanuel et Taz  ;) ), mais le parenthésage autour de "while ((lettre=...))" n'est pas correct. Bon, il est bluffant et on s'est tous fait avoir... mais si on regarde bien, lettre ne reçoit que le résultat de la comparaison de "fgetc()" avec EOF...
=> while ((lettre=fgetc(fd)) != EOF)
 
 
Bon, dernière remarque conceptuelle: Penses-tu pouvoir vraiment réaliser une fonction qui stocke dans un buffer un fichier complet ? Même avec des malloc et des realloc, si le fichier est plus gros que ta mémoire ça ne tiendra jamais...
 

Taz a écrit :

sinon t'as le droit de faire un fread hein ...


C'est vrai que cette fonction m'était sortie de la tête  :jap:


Message édité par Sve@r le 14-04-2006 à 10:20:43

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

Marsh Posté le 15-04-2006 à 14:31:04    

merci et dsl pour les retard.
 
C'est bon la fonction marche... avec un scanf() et strcat() (sans les espaces ca m'arrange).
 
Sinon pour la tyaille du fichier ca n'a pas d'importance, il ne devrait pas contenir grand chose et je vais rajouter un controle a Read_File()
 
Merci, pour l'aide

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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