écrire dans un fichier

écrire dans un fichier - C++ - Programmation

Marsh Posté le 05-02-2003 à 10:18:23    

Je souhaite écrire dans un fichier en mode append (nom du fichier : filename)
 
ofstream Sortie( filename, ios::app );
 
Contexte :
j'ai une classe out
je souhaite :  
- ouvrir le fichier dans le constructeur.
- faire des écritures dans les fonctions membres (sans avoir à ouvrir le fichier et le refermer, car déjà ouvert)
- fermer le fichier dans le destructeur
 
Est-ce possible ?
 
J'ai bien essayé de créer un objet ofstream Sortie comme donnée membre mais cela ne marche pas... :cry:
 
Tout ça, c'est pour éviter d'ouvrir et de fermer le fichier à chaque fois qu'on y écrit qq chose.
 
Question : comment dois-je m'y prendre ?
 
kason
 
:hello:


---------------
Seul le calme paisible d'un lac peut endiguer la force furieuse d'un torrent.
Reply

Marsh Posté le 05-02-2003 à 10:18:23   

Reply

Marsh Posté le 05-02-2003 à 10:24:23    

Pourquoi le fait de déclarer Sortie en variable membre ne fonctionne pas :??:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 11:25:03    

En fait, dans la classe out, je déclare un objet ofstream comme donnée membre (protected)
 
std::ofstream Sortie;
 
autre donnée membre :
char *filename;
 
Puis, dans le constructeur, j'écris :
 

Code :
  1. Sortie( filename, ios::app ); // refusé à la compilation
  2. // erreur : no match for call '(std::ofstream) (char*&, const std::_Ios_Openmode&)'


 
:??:
 

Code :
  1. ofstream Sortie( filename, ios::app ); // fonctionne mais à l'exécution rien n'est écrit (instanciation locale au constructeur)


 
NB. impossible d'écrire std::ofstream Sortie( filename, ios::app ); dans la classe -> erreur sur filename
 
kason


---------------
Seul le calme paisible d'un lac peut endiguer la force furieuse d'un torrent.
Reply

Marsh Posté le 05-02-2003 à 12:21:00    

le premier paramètre du constructeur de ofstream est un const char* et toi tu lui fournis un char *... normal !
 
il faut lire les messages du compilateur :sarcastic:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 15:07:43    

Je me demande si cette méthode est possible (ouvrir le fichier dans un constructeur, écrire via les méthodes de la classe, et fermer le fichier dans le destructeur)  :??:  
 
J'ai essayé en créant une donnée membre :
ofstream Sortie;
 
Marche pas  :fou:  
 
+ d'infos sur l'implémentation :
 

Code :
  1. class out
  2. {
  3. private:
  4. char *filename;
  5. ofstream Sortie;
  6. public:
  7. out(char *name);
  8. ~out();
  9. void f1();
  10. void f2();
  11. };
  12. out::out(char *name)
  13. {
  14.    filename = strdup(name);  // comme strcpy avec malloc implicite
  15.    Sortie( filename, ios::app); // initialisation
  16.    // refusé à la compilation...
  17.    // ofstream Sortie( filename, ios::app); est compilé mais
  18.    // à l'exécution, fichier vide  
  19.    // -> pb de portabilité de variable : conflit avec la donnée membre
  20. }
  21. out::~out()
  22. {
  23.    free(filename); // libère la mémoire (allocation dynamique)
  24.    Sortie.close(); // fermeture du fichier
  25. }
  26. out::f1()
  27. {
  28.    string Line;
  29.    Line = "titi\n";
  30.    Sortie << Line << flush;
  31. }
  32. out::f2()
  33. {
  34.    string Line;
  35.    Line = "toto\n";
  36.    Sortie << Line << flush;
  37. }


 
Des suggestions, des remarques ou une autre idée d'implémentation ?
 
kason
 
:hello:


---------------
Seul le calme paisible d'un lac peut endiguer la force furieuse d'un torrent.
Reply

Marsh Posté le 05-02-2003 à 22:30:08    

déjà, inutile de créer une variable membre filename, ça ne sert à rien vu que tu ne l'utilises que dans le constructeur.
 
ensuite, regarde la surcharge de l'opérateur << dans la classe ofstream ! il n'utilise pas de string !
 
enfin, à la place de flush, tu peux utiliser endl qui ajoute une ligne et qui flushe ensuite.
 
ce qui nous donne le code suivant :
 

Code :
  1. #include <fstream>
  2. #include <iostream>
  3. using namespace std;
  4. class out
  5. {
  6. private:
  7. ofstream *Sortie;
  8. public:
  9. out(const char *name);
  10. ~out();
  11. void f1();
  12. void f2();
  13. };
  14. out::out(const char *name)
  15. {
  16. Sortie = new ofstream(name, ios::app); // initialisation  
  17. }
  18. out::~out()
  19. {
  20. Sortie->close(); // fermeture du fichier  
  21. delete Sortie;
  22. }
  23. void out::f1()
  24. {
  25. *Sortie << "titi" << endl;
  26. }
  27. void out::f2()
  28. {
  29. *Sortie << "toto" << endl;
  30. }


en théorie, ça doit fonctionner. j'attends maintenant la réaction de Taz ou Musaran qui ne vont pas manquer de me dire que mon code est dégueulasse et/ou pas standard :d


Message édité par Harkonnen le 05-02-2003 à 22:31:28

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 22:32:23    

non c'est bon mais quel interet d'avoir un pointeur?

Reply

Marsh Posté le 05-02-2003 à 22:35:17    

++Taz a écrit :

non c'est bon mais quel interet d'avoir un pointeur?


aucun dans ce cas précis effectivement !
c'est juste une sale habitude que j'ai de déclarer des pointeurs partout :d


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 22:37:16    

ben alors enleve le

Reply

Marsh Posté le 05-02-2003 à 22:46:02    

++Taz a écrit :

ben alors enleve le


à vos ordres ! ;)
version sans pointeur :

Code :
  1. #include <fstream>
  2. #include <iostream>
  3. using namespace std;
  4. class out
  5. {
  6. private:
  7. ofstream Sortie;
  8. public:
  9. out(const char *name);
  10. ~out();
  11. void f1();
  12. void f2();
  13. };
  14. out::out(const char *name):Sortie(name, ios::app)
  15. {
  16. }
  17. out::~out()
  18. {
  19. Sortie.close(); // fermeture du fichier  
  20. }
  21. void out::f1()
  22. {
  23. Sortie << "titi" << endl;
  24. }
  25. void out::f2()
  26. {
  27. Sortie << "toto" << endl;
  28. }



---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 22:46:02   

Reply

Marsh Posté le 05-02-2003 à 22:50:55    

SETI pas bo comme ço? :jap:
 
petite remarque: beaucoup ne réalise pas que endl == '\n' + flush
 
et le flush est la plus part du temps inutile (surtout pour un fichier avec un buffer de ligne, genre terminal). endl n'est pas un '\n' plus joli à la mode C++, mais bien quelque chose de différent. il n'est pas sale de mettre des '\n' dans ses chaines de caractères

Reply

Marsh Posté le 05-02-2003 à 22:56:44    

mon code est Taz-compliant !!!! [:youpi]
 
kason > au passage, en relisant ton source, j'ai pu constater cette magnifique initialisation dans ton constructeur :
 
Sortie( filename, ios::app); // initialisation
 
pas étonnant que ça compilait pas... :sarcastic:


Message édité par Harkonnen le 05-02-2003 à 22:57:26

---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 05-02-2003 à 23:01:57    

Harkonnen a écrit :

mon code est Taz-compliant !!!! [:youpi]


 
comme quoi j'en demande pas trop...  :jap:  
 
remarque: il faut utiliser les allocateurs C++ et non malloc/free qui se contente de gérer des zone mémoire non-initaliser
 
new = constructeur+malloc
delete = destructeur+free
 
deplus ça balance des exceptions, alors que dans le cas de malloc il faut tester le pointeur.
 
bref, il faut abandonner toutes ses vieilles habitudes de C
 
 
 
et se débarasser des char* au profit des string (je veux plus voir de strdup ou d'autre truc comme ça)

Reply

Marsh Posté le 06-02-2003 à 05:48:29    

Citation :

Code :
  1. out::~out()
  2. {
  3. Sortie.close(); // fermeture du fichier
  4. }


Ce destructeur est inutile.
Les membres sont automatiquement détruits avec leur 'porteurs'.
 

Harkonnen a écrit :

le premier paramètre du constructeur de ofstream est un const char* et toi tu lui fournis un char *... normal !

Ça gène rien (c'est l'inverse qui n'est pas possible).

Code :
  1. char a;
  2. char* pa= &a;
  3. const char* cpa= pa; //ou &a

Quand un pointeur/référence se dit "sur const", ça veut dire qu'il s'engage à ne pas modifier son référent, pas que celui-ci ne peut pas changer par d'autres intermédiaires.
 
Conclusion: C++ n'a pas de spécification de constance pure pour une variable.


---------------
Bricocheap: Montage de ventilo sur paté de mastic silicone
Reply

Marsh Posté le 06-02-2003 à 06:37:42    

Musaran a écrit :

Citation :

Code :
  1. out::~out()
  2. {
  3. Sortie.close(); // fermeture du fichier
  4. }


Ce destructeur est inutile.
Les membres sont automatiquement détruits avec leur 'porteurs'.


 
tout en effet :D

Reply

Marsh Posté le 06-02-2003 à 08:53:14    

Musaran a écrit :


Ce destructeur est inutile.
Les membres sont automatiquement détruits avec leur 'porteurs'.


Encore une habitude que j'ai de toujours fermer/détruire ce que j'ouvre/construit.
 

Musaran a écrit :


Ça gène rien (c'est l'inverse qui n'est pas possible)


Oui, disons que j'étais en train de bosser quand j'ai lu son 1er post, et j'ai un peu lu ce 1er post en biais...
 


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 06-02-2003 à 13:11:35    

En suivant les tuyaux que vous m'avez donné, cela marche :wahoo:
 
Merci à tous.
 
:hello:
 
kason


---------------
Seul le calme paisible d'un lac peut endiguer la force furieuse d'un torrent.
Reply

Marsh Posté le 06-02-2003 à 13:48:49    

kason a écrit :

En suivant les tuyaux que vous m'avez donné, cela marche :wahoo:


euh, c'est plus que des tuyaux qu'on t'a filé  :whistle:


---------------
J'ai un string dans l'array (Paris Hilton)
Reply

Marsh Posté le 07-02-2003 à 13:33:34    

oui, c'est vrai  :lol:
 
kason  :whistle:


---------------
Seul le calme paisible d'un lac peut endiguer la force furieuse d'un torrent.
Reply

Sujets relatifs:

Leave a Replay

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