Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2826 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [C] [réglé] Récupérer le contenu d'un fichier texte ?

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[C] [réglé] Récupérer le contenu d'un fichier texte ?

n°1121861
_Sylver_
Posté le 16-06-2005 à 13:29:36  profilanswer
 

Bonjour, je viens vous demander un peu d'aide car là je sèche :D
Petit détail de ce que je veux faire :
J'ai un fichier nommé "test" (juste pour l'instant hein ;)) qui contient des infos que je dois analyser (une en tout cas), et des trous à remplir par l'application !
 
Le fichier se présente comme celà au début (balises de changement de ligne type unix) :

Code :
  1. 1
  2. 0.0
  3. sylver
  4. 37650432


 
J'ai choisi (mauvais choix :??:) de récupérer les informations non connues par mon appli et de reconstruire le fichier de zéro, ca m'a semblé le plus simple vu que l'appli met à jour ce fichier assez souvent !
 
j'ai fait un fichier de test pour vérifier mon analyse du fichier :

Code :
  1. #include <stdio.h>
  2. FILE *stat_tf;
  3. char *stat_file= (char*) 0;
  4. void main (void)
  5. {
  6.   int stat_state = 0;
  7.   char stat_user[80];
  8.   char stat_size[80];
  9.   stat_file = "test";
  10.   stat_tf = fopen(stat_file, "r+" );
  11.   fscanf(stat_tf, "%d%*s%*s%*s%*s%s%*s%*s%*s%*s%*s%*s%s",&stat_state, stat_user, stat_size);
  12.   printf("%d %s %d", stat_state, stat_user, stat_size);
  13. }


et voilà, mon problème c'est que quand le fichier est dans son état initial, la ligne pour lire les infos qui m'interessent est :

Code :
  1. fscanf(stat_tf, "%d%*s%s%s",&stat_state, stat_user, stat_size);


mais par la suite mon application modifie le fichier pour compléter les parties vides, et quand le fichier est completement rempli, la ligne qui lit correctement le fichier est alors :

Code :
  1. fscanf(stat_tf, "%d%*s%*s%*s%*s%s%*s%*s%*s%*s%*s%*s%s",&stat_state, stat_user, stat_size);


exemple de fichier "test" rempli :

Code :
  1. 1
  2. 0.0
  3. 1
  4. 2
  5. 33
  6. sylver
  7. 11
  8. 55
  9. 77
  10. 99
  11. 55
  12. 22
  13. 37650432


 
Le problème (ou j'ai cherché un moment) vient du fait que fscanf considère les retours chariots comme du vent et passe aux prochaines infos utiles => pleins de retours chariot sont équivalent à un espace par exemple ! Ca n'arrange pas du tout mes affaires, donc si vous aviez un piste pour que je m'en sorte, ça serait cool (par exemple un balise type %[] pour que fscanf considère les \n comme de l'info ou éventuellement un approche différente basée sur autre chose que du fscanf :sweat:)
 
Merci d'avance :jap:
 
Sylver


Message édité par _Sylver_ le 16-06-2005 à 16:48:35
mood
Publicité
Posté le 16-06-2005 à 13:29:36  profilanswer
 

n°1121872
Taz
bisounours-codeur
Posté le 16-06-2005 à 13:39:39  profilanswer
 

c'est du C

n°1121875
shikra
life is short,drink faster!!!
Posté le 16-06-2005 à 13:41:24  profilanswer
 

lol +1 pour taz

n°1121882
_Sylver_
Posté le 16-06-2005 à 13:45:39  profilanswer
 

Oui c'est du C pour le test, mais mon appli finale est en C++, je ne suis donc pas limité aux primitives C ...
 
Des idées ?


Message édité par _Sylver_ le 16-06-2005 à 13:46:37
n°1121884
Taz
bisounours-codeur
Posté le 16-06-2005 à 13:48:11  profilanswer
 

ben fais le en C++ alors avec des std::string et VERIFIE que les fonctions d'E/S n'échoue pas (si tu sors une seule fois un eof, je me casse)

n°1121889
_Sylver_
Posté le 16-06-2005 à 13:53:45  profilanswer
 

Ca a l'air tellement simple :D (je ne manipule pas souvent les chaines de caractères, c'est pour ça que je ne connais que le scanf :D), je vais chercher sur google :D, en tout cas tu me confirmes que j'aurais toutes les opérateurs pour faire ce que je souhaite ?
 
Merci en tout cas !
 
PS : pourquoi les fonctions d'IO échoueraient ?

n°1122056
_Sylver_
Posté le 16-06-2005 à 15:16:05  profilanswer
 

Je déplace dans [C] car en C++ c'est un peu lourd je trouve !
Edit : bon j'ai trouvé une méthode qui marche, à base de gros fseek des familles !
 

Code :
  1. #include <stdio.h>
  2. FILE *stat_tf;
  3. char *stat_file= (char*) 0;
  4. void main (void)
  5. {
  6.   int stat_state = 0;
  7.   char stat_user[80];
  8.   char stat_size[80];
  9.   long int offset;
  10.   int  compteur;
  11.   stat_file = "test";
  12.   stat_tf = fopen(stat_file, "r+" );
  13.   /* Get state */
  14.   fscanf(stat_tf, "%d", &stat_state);
  15.   /* Jump to owner line */
  16.   for (compteur=0;compteur<6;compteur++){
  17. while (fgetc(stat_tf) != '\n'){
  18.  offset++;
  19.  fseek (stat_tf,offset,SEEK_SET);
  20. }
  21.     offset++;
  22.     fseek (stat_tf,offset,SEEK_SET);
  23.   }
  24.   fscanf(stat_tf, "%s", stat_user);
  25.  
  26.   /* Jump to size line */
  27.   for (compteur=0;compteur<8;compteur++){
  28. while (fgetc(stat_tf) != '\n'){
  29.  offset++;
  30.  fseek (stat_tf,offset,SEEK_SET);
  31. }
  32.     offset++;
  33.     fseek (stat_tf,offset,SEEK_SET);
  34.   }
  35.   fscanf(stat_tf, "%s", stat_size);
  36.  
  37.   printf("%d %s %d", stat_state, stat_user, stat_size);
  38. }


 
C'est moche mais ça marche ! En attendant de trouver mieux, au moins je peux avancer ;)


Message édité par _Sylver_ le 16-06-2005 à 15:44:39
n°1122369
Taz
bisounours-codeur
Posté le 16-06-2005 à 18:11:50  profilanswer
 

et bien pris pour que ton fichier soit bien formé ... parce que là c'est n'importe quoi

n°1122432
Elmoricq
Modérateur
Posté le 16-06-2005 à 19:22:44  profilanswer
 

[:hide]  
 
C'est ni du C++, ni du C. C'est portnawak.
 
Je me permets de commenter :
 

Code :
  1. #include <stdio.h>
  2. /* ERK ! Pourquoi des globales ?! */
  3. FILE *stat_tf;
  4. /* re-ERK ! tu as donc *stat_file = NULL, je parie que tu  
  5.    ne lui alloueras rien en memoire, invoquant un superbe
  6.    comportement indefini. Voyons la suite */
  7. char *stat_file= (char*) 0;
  8. /* Non : main() est cense retourner un int.
  9.    donc : int main(void) */
  10. void main (void)
  11. {
  12.   int stat_state = 0;
  13.   char stat_user[80];
  14.   char stat_size[80];
  15.   long int offset;
  16.   int  compteur;
  17.   /* bingo, le beau comportement indefini que voila. Tu n'as  
  18.      absolument aucun espace memoire pour stocker ta chaine  
  19.      dans stat_file. Ca passe ou ca casse (coredump sous *nix,
  20.      violation machin error sous windows), c'est aleatoire.
  21.      Voir malloc() pour corriger ca, au plus vite */
  22.   stat_file = "test";
  23.   /* admettons que fopen() echoue, genre le fichier existe pas,
  24.      tu n'as pas les droits ou autre, stat_tf == NULL.
  25.      Il faut le tester pour s'assurer que tout fonctionne.
  26.      Et je ne vois pas l'utilité du "+" dans "r+" */
  27.   stat_tf = fopen(stat_file, "r+" );
  28.   /* Pourquoi pas, mais ce serait bien... voire necessaire, de
  29.      verifier que fscanf() a reussi a recuperer un entier. */
  30.   fscanf(stat_tf, "%d", &stat_state);
  31.   /* Ton programme n'a decidement aucune chance
  32.      face a la moindre malformation de ton fichier. */
  33.   for (compteur=0;compteur<6;compteur++){
  34.         /* Oh, le beau while (fgetc() ...)
  35.            Pourquoi ne pas plutot utiliser fgets() ? */
  36. while (fgetc(stat_tf) != '\n'){
  37.                 /* offset++ ?! Mais il n'est jamais  
  38.                    initialisé, il y a potentiellement
  39.                    n'importe quoi dedans ! */
  40.  offset++;
  41.                 /* WTF ?! fseek() ? */
  42.  fseek (stat_tf,offset,SEEK_SET);
  43. }
  44.     /* o_O */
  45.     offset++;
  46.     fseek (stat_tf,offset,SEEK_SET);
  47.   }
  48.   /* Ouh la la. Mais comment ca arrive a fonctionner tout ca  
  49.      Usine a gaz. */
  50.   fscanf(stat_tf, "%s", stat_user);
  51.  
  52.   /* Ok. En fait c'est pas une usine a gaz, c'est Tchernobyl */
  53.   for (compteur=0;compteur<8;compteur++){
  54. while (fgetc(stat_tf) != '\n'){
  55.  offset++;
  56.  fseek (stat_tf,offset,SEEK_SET);
  57. }
  58.     offset++;
  59.     fseek (stat_tf,offset,SEEK_SET);
  60.   }
  61.   fscanf(stat_tf, "%s", stat_size);
  62.  
  63.   printf("%d %s %d", stat_state, stat_user, stat_size);
  64. }


 

Citation :


C'est moche mais ça marche ! En attendant de trouver mieux, au moins je peux avancer ;)


 
C'est pire que ça.
Avancer sur une telle base, c'est courir à la catastrophe. Enfin "courir à la catastrophe", disons plutôt que tu viens de t'asperger d'essence, habillé par un pagne en paille, en train de tourner tes saucisses sur le barbecue, et que non content de la situation, tu décides d'allumer une clope en prime.
 
Sérieusement, commence par une base solide et bien plus saine que cela, parce que là c'est ignoble.
Vu ton fichier, je lirais tout bêtement le fichier ligne à ligne, en stockant au passage toutes les lignes non vides, pourquoi pas dans une liste chaînée.
Je me débrouillerais ensuite pour tester l'intégrité des données lues.
Une fois ça fait, le plus dur est passé. Il suffit de compléter la liste chaînée, et de la stocker dans un nouveau fichier.


Message édité par Elmoricq le 16-06-2005 à 19:30:15
n°1122446
skelter
Posté le 16-06-2005 à 19:55:44  profilanswer
 

je ne suis pas d'accord pour
stat_file = "test";
 
c'est moche oui, mais le comportement n'est pas indefinis, tu affecte au pointeur l'adresse d'un tableau constant

mood
Publicité
Posté le 16-06-2005 à 19:55:44  profilanswer
 

n°1122620
_Sylver_
Posté le 17-06-2005 à 00:14:52  profilanswer
 

- Oui oui pour le stat_file = "test", pas de soucis de mémoire, on mets juste à jour le pointeur vers une zone prédéfinie par le compilo !
Mais bon c'est pas fait comme ça dans le vrai soft (passage du nom par parametre, là c'est un soft de test !
- J'avais bien oublié le offset = 0 au début (pas vu car sous windows c'était mis à 0 sans init) !
- le r+, c'est parceque la suite de mon soft réécrit les infos, mais bon c'est pas mis dans la partie de test en effet :)
- pour fgets(), je ne connaissais pas, je vais regarder :jap:
- Et en effet, fichier mal formaté = cata :D
 
Merci pour ton analyse :jap:
 
J'ai fait quelques simplifications/protections :D

Code :
  1. #include <stdio.h>
  2. FILE *stat_tf;
  3. char *stat_file= (char*) 0;
  4. void main (void)
  5. {
  6.   int stat_state = 0;
  7.   char stat_user[80];
  8.   char stat_size[80];
  9.   char read_char;
  10.   int  i;
  11.   stat_file = "test";
  12.   stat_tf = fopen(stat_file, "r+" );
  13.       /* Get state */
  14.       fscanf(stat_tf, "%d", &stat_state);
  15.       /* Jump to owner line */
  16.   for (i=0;i<5;i++){
  17.    while ((((read_char=fgetc(stat_tf))) != '\n')&&(read_char != EOF));
  18.   }
  19.   fscanf(stat_tf, "%s", stat_user);
  20.   /* Jump to size line */
  21.    for (i=0;i<7;i++){
  22.    while ((((read_char=fgetc(stat_tf))) != '\n')&&(read_char != EOF));
  23.   }
  24.   fscanf(stat_tf, "%s", stat_size);
  25.   printf("%d %s %s", stat_state, stat_user, stat_size);
  26. }


Message édité par _Sylver_ le 17-06-2005 à 10:01:01
n°1123788
el muchach​o
Comfortably Numb
Posté le 18-06-2005 à 09:13:55  profilanswer
 

Je rappelle que Taz a écrit

Citation :

(si tu sors une seule fois un eof, je me casse)


 :whistle:  
 
==> fgets...
 
Tout cela est bien moche, en effet.


Message édité par el muchacho le 18-06-2005 à 09:19:25
n°1123944
el muchach​o
Comfortably Numb
Posté le 18-06-2005 à 13:54:08  profilanswer
 

C'est ça, le code qui va se retrouver dans ton appli ? Et tu dis dans le titre du topic que ton pb est réglé ?? :heink:

n°1124979
_Sylver_
Posté le 20-06-2005 à 09:42:23  profilanswer
 

En effet le code est pourri, mais pour l'instant, comme il fonctionne et qu'il est protégé, je me concentre sur d'autres problèmes !
Je pense que la solution que m'a donné Elmoricq (merci beaucoup Elmoricq au fait ;)) est la plus propre (lire toutes les lignes et les stocker soit dans une liste chainée, soit dans une structure), je réécrirai le code de cette façon quand le reste fonctionnera !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [C] [réglé] Récupérer le contenu d'un fichier texte ?

 

Sujets relatifs
Mettre un fichier excel sur le webZone de texte ?
[ACCESS] recupérer champ saisie entre 2 formulairerecuperer les informations d un autre classeur
Lire la "version" d'un fichier ?Recuperer un Printf dans une variable
[VBS]Creer un fichier texte nommée avec la dateremplacer une chaine de caractère dans un fichier
Recupérer la date de la veille 
Plus de sujets relatifs à : [C] [réglé] Récupérer le contenu d'un fichier texte ?


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR