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

  FORUM HardWare.fr
  Programmation
  C++

  Parser un fichier simple en C++

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Parser un fichier simple en C++

n°1583476
Moolfreet
Posté le 07-07-2007 à 00:16:29  profilanswer
 

Bonjour à tous!
 
Je voulais savoir s'il existait un moyen simple de parser un fichier en C++ avec les stream? Je m'explique :
au début j'avais fait un code sous VC en C qui utilisait très simplement la fonction fscanf pour parser mon fichier. Ca marchait très bien en debug, mais en release ça ne marche plus du tout. Je voulais donc passer aux classes en c++, et utiliser (ifstream & cie) mais je n'ai rien trouvé d'aussi simple que:
fscanf(file,"%lf[ \t]%lf",double1,double2);
 
Mon fichier à parser est constitué de la façon suivante :
<un double><espace(s) ou tabulation(s)><un double>
<un double><espace(s) ou tabulation(s)><un double>
etc...
 
Quelqu'un aurait-il une solution?
 
Merci d'avance!


---------------
**** |\/|¤¤] [ F®££t ****
mood
Publicité
Posté le 07-07-2007 à 00:16:29  profilanswer
 

n°1583491
Ace17
Posté le 07-07-2007 à 08:50:41  profilanswer
 

Code :
  1. double d;
  2. mon_stream >> d >> std::ws >> d ;
  3. mon_stream >> d >> std::ws >> d ;
  4. mon_stream >> d >> std::ws >> d ;


 
Peut etre ?

n°1583777
IrmatDen
Posté le 08-07-2007 à 23:09:36  profilanswer
 

Ou alors, tu devrais pouvoir passer par std::copy comme ça par exemple:

Code :
  1. vector mesDoubles;
  2. copy(istream_iterator<double>(mon_stream), istream_iterator<double>(), back_inserter(mesDoubles));

n°1583787
Moolfreet
Posté le 09-07-2007 à 00:12:46  profilanswer
 

Ace17 a écrit :

Code :
  1. double d;
  2. mon_stream >> d >> std::ws >> d ;
  3. mon_stream >> d >> std::ws >> d ;
  4. mon_stream >> d >> std::ws >> d ;


 
Peut etre ?


Merci pour ta reponse :)
Alors soit je comprend pas le code, soit ca marche pas... J'ai essaye de faire un truc du genre :

Code :
  1. ifstream MonFichier;
  2. MonFichier.open(nom_du_fichier);
  3. MonFichier >> d1 >> std::ws >> d2; // 1er essai
  4. MonFichier.get() >> d1 >> std::ws >> d2; // 2eme essai
  5. MonFichier.getline() >> d1 >> std::ws >> d2; // 3eme essai...


et le tout dans une boucle pour recuperer chaque double et chaque ligne...

n°1583788
Moolfreet
Posté le 09-07-2007 à 00:13:41  profilanswer
 

IrmatDen a écrit :

Ou alors, tu devrais pouvoir passer par std::copy comme ça par exemple:

Code :
  1. vector mesDoubles;
  2. copy(istream_iterator<double>(mon_stream), istream_iterator<double>(), back_inserter(mesDoubles));



Oula c'est un peu technique pour moi, tu pourrais detailler s'il te plait?
Merci pour ta reponse
++

n°1583789
IrmatDen
Posté le 09-07-2007 à 00:29:05  profilanswer
 

Moolfreet a écrit :

Oula c'est un peu technique pour moi, tu pourrais detailler s'il te plait?
Merci pour ta reponse
++


Disons que tu vas stocker toutes les valeurs dans un conteneur, le vector n'étant qu'un exemple typique. Ensuite, tu as ton instance de ifstream (mon_stream), qui dérive d'istream. On se sert de copy pour copier (qui l'eut cru) tout les doubles contenus dans mon_stream dans le conteneur choisi en premier.
Les 2 helpers utilisés sont:
> istream_iterator qui te permet d'utiliser un flux par le biais d'un itérateur, et par extension d'utiliser les algos de la stl
> back_inserter qui instancie un itérateur d'"additions" d'objets pour tout conteneur offrant la possibilité d'ajouter un objet à la fin du conteneur (par le biais de push_back() par exemple).
 
Ensuite, il te suffit d'itérer sur ton conteneur pour faire ce que tu veux de ces valeurs.
 
Pour plus de détails sur chaque notion, je t'invite à consulter le site de sgi qui offre de bonnes explications illustrées par des exemples.

n°1583798
Moolfreet
Posté le 09-07-2007 à 01:04:45  profilanswer
 

IrmatDen a écrit :

Disons que tu vas stocker toutes les valeurs dans un conteneur, le vector n'étant qu'un exemple typique. Ensuite, tu as ton instance de ifstream (mon_stream), qui dérive d'istream. On se sert de copy pour copier (qui l'eut cru) tout les doubles contenus dans mon_stream dans le conteneur choisi en premier.
Les 2 helpers utilisés sont:
> istream_iterator qui te permet d'utiliser un flux par le biais d'un itérateur, et par extension d'utiliser les algos de la stl
> back_inserter qui instancie un itérateur d'"additions" d'objets pour tout conteneur offrant la possibilité d'ajouter un objet à la fin du conteneur (par le biais de push_back() par exemple).
 
Ensuite, il te suffit d'itérer sur ton conteneur pour faire ce que tu veux de ces valeurs.
 
Pour plus de détails sur chaque notion, je t'invite à consulter le site de sgi qui offre de bonnes explications illustrées par des exemples.


 
Merci bcp pour ta réponse, je vais essayer de voir ça :)
Sinon, par curiosité, tu ne saurais pas pourquoi fscanf ne marche pas sous VC6 en mode release?
++

n°1583802
IrmatDen
Posté le 09-07-2007 à 01:14:15  profilanswer
 

Euh, pas vraiment; mais je doute que ce soit fscanf qui ne marche pas, il faudrait voir comment tu as écrit cette ligne, ainsi que les types des paramètres concernés...

n°1583805
Moolfreet
Posté le 09-07-2007 à 01:23:28  profilanswer
 

IrmatDen a écrit :

Euh, pas vraiment; mais je doute que ce soit fscanf qui ne marche pas, il faudrait voir comment tu as écrit cette ligne, ainsi que les types des paramètres concernés...


Code :
  1. int iNbRecords(char * sFileName)
  2. {
  3. FILE * file;
  4. double x,y;
  5. int i = 0;
  6. file = fopen(sFileName, "r" );
  7. if (!file) {
  8.  // ...
  9.  return -1;
  10. }
  11.    
  12. /* %[a-zA-Z] => Indique que l'on lit uniquement les lettres de a à z, en majuscules ou non */
  13. /* %d        => indique que l'on lit un entier, que l'on place dans le second argument     */
  14. /* %*[ ]     => L'étoile (*) située après le pourcent indique que les caractères lus       */
  15. /*              (ici des espaces) ne sont pas placé dans l'argument correspondant          */
  16. /* %lf       => on lit un long float que l'on place dans le dernier argument               */
  17. while (!feof(file) && fscanf(file, "%lf%*[ \t]%lf\n" , &x, &y))
  18.  i++;
  19. fclose(file);
  20. return i;
  21. }


 
Voila l'une des fonctions que j'ai écrite pour calculer le nombre de lignes au format <double><esp/tab><double>, pour compter le nombre de points en fait (ce sont des coordonnées).
En isolant chaque partie du programme, c'est bien l'appel à fscanf qui provoque une erreur (access violation)...
++

n°1583806
IrmatDen
Posté le 09-07-2007 à 01:30:36  profilanswer
 

Là, je ne vois pas, désolé :/ (en plus je ne connaissais pas ces notations %*[...] :))

mood
Publicité
Posté le 09-07-2007 à 01:30:36  profilanswer
 

n°1583807
Moolfreet
Posté le 09-07-2007 à 01:34:23  profilanswer
 

IrmatDen a écrit :

Là, je ne vois pas, désolé :/ (en plus je ne connaissais pas ces notations %*[...] :))


Arf pas grave, en tout cas merci beaucoup pour ton aide!
++

n°1583827
Ace17
Posté le 09-07-2007 à 08:16:29  profilanswer
 

J'avais pas vu l'histoire de debug et release...
Ca m'etonnerait beaucoup que ce soit fscanf, la cause de ton probleme. A mon avis t'as un probleme ailleurs, c'est meme a peu pres certain.
 
Ce que je te conseille de faire : tu vas dans les options de ton projet pour le mode release et tu actives la debug info. Ensuite tu lances le debug et tu vois la ou ca plante.

n°1584098
Moolfreet
Posté le 09-07-2007 à 15:33:29  profilanswer
 

Ace17 a écrit :

J'avais pas vu l'histoire de debug et release...
Ca m'etonnerait beaucoup que ce soit fscanf, la cause de ton probleme. A mon avis t'as un probleme ailleurs, c'est meme a peu pres certain.
 
Ce que je te conseille de faire : tu vas dans les options de ton projet pour le mode release et tu actives la debug info. Ensuite tu lances le debug et tu vois la ou ca plante.


J'ai essayé d'activer le debug info, mais je n'arrive pas à trouver plus précisément là où ça plante, car c'est juste avant l'appel à fscanf, mais c'est tout en assembleur...
 
Sinon j'ai créé un projet rapidement sous VC, "Hello Word", dans lequel j'ai remplaçé l'appel à la dialogbox dans le menu par une fonction test() dont voici le code :

Code :
  1. void test(void)
  2. {
  3.           FILE * file;
  4.           double x = 0.0;
  5.           double y = 0.0;
  6.           file = fopen("c:\\test.txt", "r" );
  7.           if (file == NULL)
  8.               return;
  9.           MessageBox(NULL,"Avant le fscanf","Info",MB_OK);
  10.           fscanf(file, "%lf%*[ \t]%lf\n" , &x, &y))
  11.           MessageBox(NULL,"Apres le fscanf","Info",MB_OK);
  12.           fclose(file);
  13.           return;
  14. }


 
En mode debug, tout se passe bien, les deux box s'affichent. En release, la première s'affiche, puis une jolie boite de dialogue "Hello.exe a rencontré une erreur blabla... signalez ce problème à microsoft...". Lorsque je lance avec "Start Debug->Go" (F5), après avoir activé comme tu m'as dit la debug info, il me dit qu'il y a une violation d'accès et me balance sur le code assembleur où ça plante...
 
Merci pour ton aide
++

n°1584112
Un Program​meur
Posté le 09-07-2007 à 16:00:31  profilanswer
 

Je ne vois pas de raisons d'avoir fscanf qui foire ici et je ne reproduis pas le probleme chez moi (mais sous Linux).  Tu peux donner un programme console complet et le contenu de ton fichier de test?
 
(Si ton fichier contient autre chose, et que tu boucles avec une lecture comme celle-ci, tu risques d'avoir une boucle infinie).

n°1584115
Taz
bisounours-codeur
Posté le 09-07-2007 à 16:04:08  profilanswer
 

mais allez vous pendre avec vos scanf bordel !

n°1584119
Moolfreet
Posté le 09-07-2007 à 16:25:31  profilanswer
 

Un Programmeur a écrit :

Je ne vois pas de raisons d'avoir fscanf qui foire ici et je ne reproduis pas le probleme chez moi (mais sous Linux).  Tu peux donner un programme console complet et le contenu de ton fichier de test?
 
(Si ton fichier contient autre chose, et que tu boucles avec une lecture comme celle-ci, tu risques d'avoir une boucle infinie).


Voila un programme en mode console qui pose le même problème :

Code :
  1. #include <stdio.h>
  2. int main(int argc, char* argv[])
  3. {
  4.        FILE * file;
  5.        double x=0.0;
  6.        double y=0.0;
  7.        file = fopen("c:\\essai.txt","r" );
  8.        if(file == NULL)
  9.               return -1;
  10.        printf("Avant fscanf" );
  11.        fscanf(file,"%lf%*[ \t]%lf\n",&x,&y);
  12.        printf("Apres fscanf" );
  13.        printf("Valeurs lues : %lf,%lf",x,y);
  14.        return 0;
  15. }


 
Dans le fichier essai.txt il y a:
1  2
2  3
3  4
4  5
5  1
En mode débug, ça marche normalement, en mode release ça plante sur le fscanf...


Message édité par Moolfreet le 09-07-2007 à 16:28:38
n°1584122
Moolfreet
Posté le 09-07-2007 à 16:35:19  profilanswer
 

IrmatDen a écrit :

Ou alors, tu devrais pouvoir passer par std::copy comme ça par exemple:

Code :
  1. vector mesDoubles;
  2. copy(istream_iterator<double>(mon_stream), istream_iterator<double>(), back_inserter(mesDoubles));



Décidément le mode release n'est pas mon ami!!!
J'ai essayé avec ta solution, voici mon code :
 

Code :
  1. vector<double> vecDoubles;
  2. ifstream fInFile("C:\\essai.txt" );
  3. int i=0;
  4. copy(istream_iterator<double>(fInFile), istream_iterator<double>(), back_inserter(vecDoubles));
  5. i = vecDoubles.size();


Le fichier contient :
1  2
2  3
3  4
4  5
5  1  
Et en mode débug pas de problème, i vaut 10 à la fin. En mode release... i vaut 0 à la fin :'(

n°1584131
Un Program​meur
Posté le 09-07-2007 à 16:50:51  profilanswer
 

Ca s'execute sans probleme ici, que ce soit en debug ou en optimise.
 

n°1584133
Moolfreet
Posté le 09-07-2007 à 16:53:57  profilanswer
 

Un Programmeur a écrit :

Ca s'execute sans probleme ici, que ce soit en debug ou en optimise.


Sous nux je veux bien le croire, j'ai essayé avec le compilo de DevCpp, pas de problème non plus, mais j'aimerais savoir ce qui pose problème avec le compilo de VC6...

n°1584148
IrmatDen
Posté le 09-07-2007 à 17:16:55  profilanswer
 

il est foireux :P

n°1584150
Moolfreet
Posté le 09-07-2007 à 17:19:12  profilanswer
 

lol

n°1584151
Moolfreet
Posté le 09-07-2007 à 17:20:39  profilanswer
 

Sinon, IrmatDen, tu vois ce qui pose problème dans mon code avec les stream?

n°1584159
Un Program​meur
Posté le 09-07-2007 à 17:26:10  profilanswer
 

A mon avis il n'y a rien de problematique dans l'autre code non plus.  Le probleme doit venir d'une difference de l'environnement entre debug/optimise, mais je n'y connais rien sous Windows.

n°1584161
Moolfreet
Posté le 09-07-2007 à 17:28:35  profilanswer
 

Snif... y'a personne dans le coin (coin) qui aurait une idée?

n°1584164
IrmatDen
Posté le 09-07-2007 à 17:29:23  profilanswer
 

Bah si: VC++ 6 :/
Ca passe nickel sur le 2005 Express, et je doute que ça foire avec le 2003 ou encore g++.

n°1584264
Ace17
Posté le 09-07-2007 à 21:55:18  profilanswer
 

IrmatDen a écrit :

il est foireux :P

Faut pas abuser non plus. C'est vrai qu'il comporte pas mal de bugs, mais ca ne le rend pas inutilisable a ce point. Je vais lancer l'exemple de Moolfreet chez moi et on verra.

n°1584268
IrmatDen
Posté le 09-07-2007 à 22:02:56  profilanswer
 

Volontier; c'est surtout que je ne peux pas tester, et que les autres environnements que j'utilise n'ont jamais posé le moindre souci ;)

n°1584271
Ace17
Posté le 09-07-2007 à 22:05:15  profilanswer
 

Bon, c'est bien ce qui me semblait. Je viens de tester chez moi sur VC6, ca marche nickel, en debug comme en release. Moi je dis qu'il y a une erreur autre part dans ton code.
 
Et pour info, Taz a raison sur le fait qu'il ne faut pas utiliser scanf.
 

Code :
  1. ifstream fp("fichier.txt" );
  2.   fp >> x >> ws >> y;
  3.   fp >> x >> ws >> y;


 
fait tres bien l'affaire (je viens de tester). Tu as dit que tu avais teste mais tu n'as pas donne le resultat de ton test.

n°1584277
Moolfreet
Posté le 09-07-2007 à 22:30:55  profilanswer
 

Ace17 a écrit :

Bon, c'est bien ce qui me semblait. Je viens de tester chez moi sur VC6, ca marche nickel, en debug comme en release. Moi je dis qu'il y a une erreur autre part dans ton code.


Je ne comprend pas comment il pourrais y avoir une erreur ailleurs dans mon code, vu que quand je l'isole totalement ca pose le meme probleme (voir le code console plus haut)

Ace17 a écrit :


Et pour info, Taz a raison sur le fait qu'il ne faut pas utiliser scanf.


Ouep desole, vieille mauvaise habitude...

Ace17 a écrit :


Code :
  1. ifstream fp("fichier.txt" );
  2.   fp >> x >> ws >> y;
  3.   fp >> x >> ws >> y;


 
fait tres bien l'affaire (je viens de tester). Tu as dit que tu avais teste mais tu n'as pas donne le resultat de ton test.


Comme je l'ai mis plus haut ce code ne fait pas d'erreur (ni en Debug, ni en release), en debug il marche tres bien, mais en release... il renvoie x=0.000000, et y=0.000000... (precisement lol)

Message cité 1 fois
Message édité par Moolfreet le 09-07-2007 à 22:31:55
n°1584297
Ace17
Posté le 09-07-2007 à 23:13:07  profilanswer
 

Moolfreet a écrit :

Je ne comprend pas comment il pourrais y avoir une erreur ailleurs dans mon code, vu que quand je l'isole totalement ca pose le meme probleme (voir le code console plus haut)

Quand tu dis "isoler totalement" c'est bien creer un autre projet completement separe, on est bien d'accord?   :o  
 
Parce que toi et moi on a meme OS meme compilo meme code et ca donne pas la meme chose, y'a de quoi s'inquieter ... surtout si chez toi ni fscanf ni les ifstreams ne fonctionnent en mode release ..... :heink:  

n°1584299
Moolfreet
Posté le 09-07-2007 à 23:18:55  profilanswer
 

Oui oui, ce que j'appel isoler totalement, c'est bien créer un autre projet completement séparé. Donc pour le fscanf je comprend pas...
Apres, les ifstreams je les ai pas testé séparément, j'ai pas encore eu le temps.  
Pour ce qui est d'avoir le même OS, ce n'est encore moins sur, car je viens de m'appercevoir que le pc sur lequel je compilais (je suis en stage) était sous WinXP sans SP installé. Je viens de mettre à jour le SP2 et par la même occasion, j'ai aussi installer VC 2005 express pour voir si ça marche...
Affaire à suivre...

n°1584302
Ace17
Posté le 09-07-2007 à 23:20:43  profilanswer
 

T'as essaye comme je t'ai dit d'activer la debug info en mode release pour voir ce qui provoque l'erreur ?

n°1584303
Moolfreet
Posté le 09-07-2007 à 23:22:41  profilanswer
 

Oui oui, et comme je t'ai répondu, je tombe sur du code assembleur dans tout les coins, et je sais pas trop où chercher précisément...

n°1584305
Ace17
Posté le 09-07-2007 à 23:33:43  profilanswer
 

Au temps pour moi, j'avais loupe ta reponse. C'est bizarre ton probleme. A mon avis, si on teste un peu, on va trouver d'autres trucs qui ne marchent pas en release chez toi ... Tu veux pas faire un zip avec un mini projet qui plante ou tu incluerais source+dsw/dsp+binaires ?

n°1584319
Moolfreet
Posté le 10-07-2007 à 01:06:32  profilanswer
 

Voilou : y'a tout là dedant : http://y.lemaout.free.fr/public/test_scanf.rar
 
Sinon je voulais savoir, vu que là il va falloir que je reprenne tout mon code pour VC 2005 express (mon code qui marchait en Debug sous VC6 a plein d'incompatibilités) si le compilo de VC 2005 Express était mieux ou pas que celui de VC++ 6 Pro. Je pense que certains vont me dire que on peut pas trop comparer, mais mon programme effectue des opérations lourdes en temps de calcule et en mémoire... donc j'aimerais bien savoir...

Message cité 1 fois
Message édité par Moolfreet le 10-07-2007 à 21:32:00

---------------
**** |\/|¤¤] [ F®££t ****
n°1584985
Moolfreet
Posté le 10-07-2007 à 21:33:04  profilanswer
 

Bon sinon j'ai repris le même code et tout recompilé sous VC 2005 express et tout marche bien !

n°1584992
_darkalt3_
Proctopathe
Posté le 10-07-2007 à 22:01:41  profilanswer
 

Moolfreet a écrit :

Voilou : y'a tout là dedant : http://y.lemaout.free.fr/public/test_scanf.rar
 
Sinon je voulais savoir, vu que là il va falloir que je reprenne tout mon code pour VC 2005 express (mon code qui marchait en Debug sous VC6 a plein d'incompatibilités) si le compilo de VC 2005 Express était mieux ou pas que celui de VC++ 6 Pro. Je pense que certains vont me dire que on peut pas trop comparer, mais mon programme effectue des opérations lourdes en temps de calcule et en mémoire... donc j'aimerais bien savoir...


 
VC6 Comme VS2005 peuvent tous deux traiter des "opérations lourdes" sans problème ...
C'est pas vraiment comparable [:god]


---------------
Töp of the plöp
mood
Publicité
Posté le   profilanswer
 


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

  Parser un fichier simple en C++

 

Sujets relatifs
trouver un fichier et supprimer les autresExtraction de données à partir d'un fichier
[EXCEL] Insérer contenu d'une feuille dans un autre fichier[PHP] Upload par fichier le retour !
Requete UPDATE et parcourt de fichierprobleme fichier téléchargé avec telechargement forcé de php
[Collections]Collection intermédiaire pour stocker dans un fichierC++ comment ouvrir et lire un fichier sur serveur distant ?
[Macro Excel] Sauvegarder une sélection en fichier platFichier dev c++ en mode wxwidgets dialog
Plus de sujets relatifs à : Parser un fichier simple en C++


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