sauvegarde dans un fichier C++

sauvegarde dans un fichier C++ - Programmation

Marsh Posté le 12-06-2001 à 22:38:46    

Comment sauvegarder toute une liste d'éléments ( liste à double chaînage), dans un fichier ?
 
 
 
Je dois utiliser ifstream ou fwrite ?

Reply

Marsh Posté le 12-06-2001 à 22:38:46   

Reply

Marsh Posté le 12-06-2001 à 22:45:17    

help please !

Reply

Marsh Posté le 12-06-2001 à 23:06:39    

ben utilise un ostream
(o comme out)
 
exemple:
 
#include <fstream>
using namespace std;
classe MonType
{
public:
 int a;
 float c;
 friend ostream & operator << (ostream & out, const MonType & obj);
};
//par exemple
 
ostream & operator << (ostream & out, const MonType & obj)
{
 out << a << ' ' << c << ' ';
 return out;
}
 
 
 
void main()
{
ostream out("data.txt" );
MaListe<MonType> liste;
ListeNoeud * n=liste.debut();
while (n!=NULL)
{
 out<< *n->val;
 n=n.suivant;
}
 
ça c'est pour les types maison

Reply

Marsh Posté le 12-06-2001 à 23:10:44    

si t'utilises les listes de la stl,
voici le code
 
#include <list>
using namespace std;
 
ostream out("data.txt" );
list<MonType> liste;
...
copy(liste.begin(), liste.end(), output_iterator<MonType>(out));
 
et ça ça marche.
 
 
 
 
ou bien,
moins futé mais plus lisible:
 
ostream out("data.txt" );
list<MonType> liste;
 
for (list<MonType>::const_iterator p=liste.begin(); p!=liste.end(); p++)
    out<<*p<<' ';
 
out.close();
 
 
et voilà

Reply

Marsh Posté le 12-06-2001 à 23:14:02    

Je vais être un peu plus précis.
Il y a une procédure qui construit la liste en question :
Il y a 2 procédures pour ajouter des éléments à la liste  
ajouto (oui) et ajoutn ( non).
a chaque lancement de programme cette construction se fait.
Tlist l  
void remplir()
{
Char v[100];
Telement *x1,*x2; //permet de mettre des point de repère dans
// la construcion de la liste)
 
strcpy(v,"Question1" )
ajouto(l,v);
x1=l.ec
strcpy(v,"Question1" )
ajouto(l,v);
x2=l.ec
...
strcpy(v,"Reponse" )
ajoutn(l,v);
}
 
MAIS, ensuite des nouvelles reponse peuvent être ajoutées, si elle est inexistante dans la liste précedemment construite.
LORS d'un usage ultérieur, ces modif ne sont pas sauvegardées !
Donc voilà pourkoi  la nécessité de copier toute la structure de la liste dans un fichier et ensuite de mettre à jour ce fichier a chaque sortie pour sauvegarder les nouvelles reponse (ou question ajoutées)

Reply

Marsh Posté le 12-06-2001 à 23:19:08    

en me relisant, je me suis dit que j'y suis peut être allé un peu cash!
 
Donc en fait, le problème est différent selon si tu as ta propre classe de liste chainées, ou si t'utilises celle de la STL (ce que je recommande, car elle est style. Je pense que même si on fait sa propre classe de liste chainée, il faut voir celle de la STL pour éviter de réinventer la roue)
 
Dans tous les cas, il faut que tu surcharges la fonction
ostream & operator << (ostream & out, const MonType & obj);
pour pouvoir écrire ton propre type au même titre que les entiers, les flottants ou autres types système.
tu pourras donc même faire
MonType machin;
cout << machin;
si tu veux.
 
Ensuite, écrire la séquence se fait comme je te l'ai dit pour la STL.
Si tu utilises ton propre type, j'ai donné un exemple avec ce que je crois ressemble à une implémentation de liste chainée version pas STL, mais bon, il faudra l'adapter à ta sauce.
Si t'utilises pas les templates, oublie les trucs entre <  >.
good luck!

Reply

Marsh Posté le 12-06-2001 à 23:22:01    

j'écrivait mon 3ème post alors que tu écrivais le tien.
Attends, je réfléchis...

Reply

Marsh Posté le 12-06-2001 à 23:24:56    

attends, je ne suis pas sur de savoir ce qu'est ec, ni à quoi servent x1 et x2.
Toujours est-il que j'entrevois un méchant effet de bord avec v qui ne bouge pas, mais qui est inséré, mais peut-être que je me trompe car je n'ai pas saisi le prob.
Si tu pouvais être plus spécifique sur le but à atteindre, ça m'aiderait bcp (et toi aussi, par la même occasion).

Reply

Marsh Posté le 12-06-2001 à 23:28:43    

merci  !
mais ma liste est à double chaînage et l'odre est important !
 
              ->oui -->R1    
 
  ->oui -->Q2 ->non -->R2
Q1
 
  ->non -->Q3 ->oui -->R3
 
              ->non -->R4
 
Si la réponse n'existe pas alors on a le changement suivant :
et admettons qu'elle concerne Q3
 
 
Q1...  -->Q3 ->oui -->R3
 
             ->non -->Q4  ->oui  -->R5   (ici la modif)
 
                          ->non  -->R4  
 
 
Je veux que tout ces changements soit sauvegarder dans le fichier...

Reply

Marsh Posté le 12-06-2001 à 23:32:20    

attends, c'est barbare pour moi qui ne connait pas le problème.
T'as une ou plusieurs listes?
Les réponses, c'est soit oui soit non?
Le but du jeu c'est quoi?
 
En fait le problème, c'est que je ne sais pas ce que tu mets dans la liste, et pourquoi tu fais la modif? Je suis dans le noir.
Prends 5 min pour décrire le problème (pas l'obstacle sur lequel tu butes, mais l'objectif du programme), et là, je pourrai t'aider. No prob.

Reply

Marsh Posté le 12-06-2001 à 23:32:20   

Reply

Marsh Posté le 12-06-2001 à 23:33:56    

je n'utilise pas des classes mais uniquement les struc suivantes :
 
typedef struct Telement
{
char v[100]; // les fameuses questions ou reponse
Telement *so;
Telement *sn;
}Telement;
 
typedef struct
{
Telement *tete;
Telement *ec;
}Tliste;
 
et POUR ls ajouts :
 
void ajouto (Tliste &l, char val[100])
{
Telement *x;
 if (listevide (l))
   {x = new (Telement);
   strcpy(x->v,val);
   (x->so) = NULL;
   (x->sn) = NULL;
   (l.tete)=x;
   (l.ec)=x; }
   else {
     if (l.ec==NULL)
         {cout<< "erreur sur ajouto !";}
         else {
         x = new (Telement);
         strcpy(x->v,val);
           (x->so) = NULL;
           (x->sn) = NULL;
           (l.ec->so) = x;
           (l.ec) = x;
          };
   };
}
 
 
void ajoutn (Tliste &l, char val[100])
{
Telement *x;
 if (listevide (l))
   {x= new (Telement);
   strcpy(x->v,val);
     (x->sn) = NULL;
     (x->so) = NULL;
    (l.tete)=x;
    (l.ec)=x;}
    else {
     if (l.ec==NULL)
         {cout<< "erreur sur ajoutn !";}
     else {
         x=new (Telement);
         strcpy(x->v,val);
           (x->so)=NULL;
          (x->sn)=NULL;
          (l.ec->sn) = x;
          (l.ec) = x;
        };
   };

Reply

Marsh Posté le 12-06-2001 à 23:45:08    

aha, c'est un arbre ton truc, en fait,
le C ça me bouzille les neurones, mais bon, c'est parti:
dans tous les cas, utiliser les string C++, ça t'épargnera du merdier, car y'a plus de new, plus de strcpy, ni tout le reste.
en plus y'a l'op ==, et le constructeur par recopie, et le destructeur qui libère la mémoire le moment venu.
 
 
je réfléchis un peu et je te réponds.

Reply

Marsh Posté le 12-06-2001 à 23:51:34    

J'ai une seule liste mais chaque element possède deux pointeurs
(*so et *sn)1 qui pointe vers une oui si l'utilisateur réponds oui.
par exemple ,l'enfant pense à un animal, et le PC lui pose des questions pour deviner l'animal.
Q1 : " A-til des grandes oreilles ?"  
SI   oui -> Q2 " Mange-t-il des carottes ?"
SI   non -> Q3 "Est-il canivore ?"
 
à ce stade le PC propose un animal à l'enfant  
admettons que l'enfant ait repondu oui a Q1
On arrive à Q2 -> il répond oui -> on a R1, donc le PC affiche "l'animal recherché est le LAPIN ?"  
si l'enfant répond oui alors le PC a gagné.
Si l'enfant repond non c'est lui qui gagne. et c'est ici qu'intervient les modifications ALors
On lui dit d'entrer le nom de l'animal auquel il a pensé  
cin<<Newanimal;
et on lui demande d'entrer une question pour le différencier du lapin
Cin>>Q4;
Ainsi notre liste s'agrandie :
a la place de R1 on aura une nouvelle question Q4!
 
-->Q4 : oui ->R5 (="gremlins" )
        non ->R1 (="lapin"
 
 
(n.b. : les exemples sont bidons je sais !)

Reply

Marsh Posté le 12-06-2001 à 23:53:40    

ça pourra t'aider un peu :
void remplir()
{ // début remplir
initliste(l);
ostream out("data.txt" );
Telement *x1,*x2;
char v[100];
strcpy(v,"\n A-t-il des grandes oreilles ? : " );
ajouto(l,v);
x1=l.ec;
strcpy(v,"\n Mange-t-il des carottes ? : " );
ajouto(l,v);
x2=l.ec;
l.ec=x1;
strcpy(v,"\n Est-il carnivore ? : " );
ajoutn(l,v);
x1=l.ec;
strcpy(v,"\n Loup" );
ajouto(l,v);
l.ec=x1;
strcpy(v,"\n Cheval" );
ajoutn(l,v);
l.ec=x2;
strcpy(v,"\n Lapin" );
ajouto(l,v);
l.ec=x2;
strcpy(v,"\n Kangourou" );
ajoutn(l,v);
   } // fin remplir
 
void question()
{ // début procedure question
char rep;
char v[100];
entete(l);
 
do
{
valec(l,v);
cout << v;
cout <<"\n O pour oui, N pour non : ";
cin >> rep;
 if (rep=='O' || rep=='o')
   {suco(l);}
   else {
   sucn(l);};
}
while ((l.ec->sn!=NULL )&& (l.ec->so!=NULL));
 
} // fin procedure question
 
 
void jeu()
{ //début procedure jeu
Telement *x1;
char rep;
char animalanc[50];
char v[100];
char animalnouv[50];
char question2[150];
question();
valec(l,v);
cout <<" \n L'animal recherche est-il le :"<<v; cout<<" ( O/N ) ?  : ";
cin >> rep;
 if (rep=='o' || rep=='O')
   {cout << " \n J'ai gagne !";}
   else {cout<< "\n Tu as  gagne !, entre le nom de l'animal auquel tu pensais : ";
     strcpy(animalanc,(l.ec->v));
         x1=(l.ec);
         cin>>animalnouv;
         ajouto(l,animalnouv);
         cout<< "\n Entres une question pour differencier les 2 animaux : ";
         cin >> question2;
         (l.ec)=x1;
         modifec(l,question2);
         ajoutn(l,animalanc);
         }; //fe
 
 
} // fin procedure jeu

Reply

Marsh Posté le 13-06-2001 à 00:15:16    

voici une idée
choisis un sens de parcours, disons oui, puis non, comme ça:
 
#include <iostream>
using namespace std;
 
ostream & operator << (ostream & out, const Telement & e)
{
 out << v << endl; // endl=='\n'
 out << "{\n";
 if (so!=NULL)
  out << *so;
 if (sn!=NULL)
  out << *sn;
 out << "}\n";
 return out;
}
 
ostream & operator << (ostream & out, const Tlist & l)
{
 if (ec!=NULL)
  out << *ec;
 return out;
}
 
 
 
tu peux donc écrire par la suite
 
Tliste l;
...
cout << l;
 
ou bien
 
ostream file("data.txt" );
file << l;
 
et ça marchera.
Je ne suis pas sur de comprendre l'intérêt de tete, car ce n'est pas une liste chainée mais en fait un arbre binaire si j'ai bien pigé.
 
Si tu veux, tu me donne le fond de ton problème et je te propose ma soluce.

Reply

Marsh Posté le 13-06-2001 à 00:26:37    

Voici mon idée:
t'as un ensemble d'animaux avec un ensemble de propriétés:
genre
 
lapin:(poils:oui),(pattes:4),(herbivore:oui)
mouche:(ailes:oui)
chat:(poils:oui),(pattes:4),(herbivore:non)
chien:(poils:oui),(pattes:4),(herbivore:non)
 
en fait ca devient un tableau
 
          poils         pattes      ailes      herbivore
lapin     oui           4           ?          oui
mouche    ?             ?           oui        ?
chat      oui           4           ?          non
chien     oui           4           ?          non
donc voilà
L'ordi pose une QCM sur un attribut pour diviser au mieux la base de données des animaux, et ainsi de suite, jusqu'au moment où tous les animaux qui lui restent vérifient ces attribut donnés en réponse jusqu'ici.
Alors là, il lui reste peut être des attributs non spécifiés
 
genre par exemple
Q1: herbivore
->oui
->non
R1 oui,
donc le choix se fige à {chat, mouche, chien)
donc l'ordinateur ne sait plus départager.
Donc il va demander si la mouche a des poils ou le chat a des ailes.
Il essaie de compléter les valeurs des attributs pour la base de données qu'il a.
Lorsque tout le monde a des valeurs pour les attributs, il faut demander un nouvel attribut pour s'en sortir.
...
Mais à implémenter, il me faudrait qqes heures.
 
en fait les questions cherchent d'abord à boucher les ?,
puis à rajouter des colonnes d'attributs.

n°39260
janoscoder
Posté le 13-06-2001 à 00:29:39  profilanswer
 

ET sans les smileys:
 
Voici mon idée:
t'as un ensemble d'animaux avec un ensemble de propriétés:
genre
 
lapin:(poils:oui),(pattes:4),(herbivore:oui)
mouche:(ailes:oui)
chat:(poils:oui),(pattes:4),(herbivore:non)
chien:(poils:oui),(pattes:4),(herbivore:non)
 
en fait ca devient un tableau
 
          poils         pattes      ailes      herbivore
lapin     oui           4           ?          oui
mouche    ?             ?           oui        ?
chat      oui           4           ?          non
chien     oui           4           ?          non
donc voilà
L'ordi pose une QCM sur un attribut pour diviser au mieux la base de données des animaux, et ainsi de suite, jusqu'au moment où tous les animaux qui lui restent vérifient ces attribut donnés en réponse jusqu'ici.
Alors là, il lui reste peut être des attributs non spécifiés
 
genre par exemple
Q1: herbivore
->oui
->non
R1 oui,
donc le choix se fige à {chat, mouche, chien)
donc l'ordinateur ne sait plus départager.
Donc il va demander si la mouche a des poils ou le chat a des ailes.
Il essaie de compléter les valeurs des attributs pour la base de données qu'il a.
Lorsque tout le monde a des valeurs pour les attributs, il faut demander un nouvel attribut pour s'en sortir.
...
Mais à implémenter, il me faudrait qqes heures.
 
en fait les questions cherchent d'abord à boucher les ?,
puis à rajouter des colonnes d'attributs.

n°39261
jibix
Posté le 13-06-2001 à 00:38:41  profilanswer
 

entete permet d'être sûr qu'on est sur Q1. bon ça c'est pas grave.
 
 
Mais ce que j'ai du mal à piger c'est comment mettre en oeuvre cette sauvegarde. c'est à dire quelles sont les variables ( ormis v) que je dois extraire?
Je t'envois le prog principal :
Liste1.h ( je tenvois la 1ère partie" car ajouto et ajoutn tu as dejà
 
//************LISTE1.H********************
 
void initliste(Tliste &l)
{
l.tete=NULL;
l.ec=NULL;
}
 
 
bool listevide (Tliste l)
{
return(l.tete==NULL);
}
 
void entete(Tliste &l)
{
l.ec=l.tete;
}
void suco(Tliste &l)
{
if (l.ec==NULL)
 {cout <<"\n Erreur sur suco!" ;
 getch();}
 else
 {l.ec=(l.ec->so);};
}
void sucn(Tliste &l)
{
if (l.ec==NULL)
{cout <<"\n Erreur sur sucn!" ;
 getch();}
 else
 {
  l.ec=(l.ec->sn);};
}
void valec(Tliste &l,char val[100])
{
if (l.ec==NULL)
   { cout << " erreur sur valec!";
     getch(); }
   else{
  strcpy(val,l.ec->v);};
}
void modifec(Tliste &l, char val[100])
{
if (l.ec==NULL)
 {cout << "erreur sur modifec!";}
   else {
   strcpy(l.ec->v,val);};
// ne pas oublier ajouto et ajoutn
//****FIN LISTE1.H**************
 
// liste2.h regroupe les procédures remplir(),question() et  
// jeu()
 
//******************* MAIN**************
#include <stdio.h>
#include <iostream.h>
#include <fstream.h>
#include <conio.h>
#include <cstring.h>
#include <dos.h>
 
typedef struct Telement
{
char v[100];
Telement *so;
Telement *sn;
}Telement;
 
 
typedef struct
{
Telement *tete;
Telement *ec;
}Tliste;
 
int choix,nb_sec=5,a=1;
Tliste l;
#include "c:\ap\animofinal\liste1.h"
#include "c:\ap\animofinal\liste2.h"
 
main()
{   // debut  PP
entete(l);
remplir();
do
{  // proc repeter
cout << "\n\n\t ANI<->MOT\t" ;
cout << " \n 1) Jouer a animo ";
cout << " \n 2) Quitter ";
cout <<" \n entrez votre choix : " ;
cin >> choix;
cout<< "\n\nPense a un animal\n\n";
for (nb_sec;nb_sec>=0;nb_sec--)
{
clrscr();
cout<<nb_sec;
sleep(a);
//
}
clrscr();
// appel des procedures
switch (choix) {
  case 1 : //question();
           jeu();
           break;
  default : break;
}  // fin choix
 
}
 while (choix!=2);
 
getch();
} //fin programme principal
//*****************************FIN***********

Reply

Marsh Posté le 13-06-2001 à 00:43:44    

C clair que ton idée semble bonne, surtout c'est plus facile de sauvegarder dans un ficher.
Mais je dois absolument utiliser des listes.
 
Mais je pense qu'avec le post précédent, tu comprendra mieux où je veux en venir.
 
(nahimz@free.fr)

Reply

Marsh Posté le 13-06-2001 à 00:45:29    

ostream
o-> output  
 
Mais moi ce que je veux ces des "input" ecrire des données dans un fichier...

Reply

Marsh Posté le 13-06-2001 à 00:48:20    

holà!
c'est trop gros pour mon petit cerveau, mais le code que je t'ai donné devrait fonctionner avec le tien.
La feinte, c'est de sauvegarder le noeud, son fils oui, puis son fils non.
 
ça veut dire qu'avec le code que je t'ai donné, ça donne:
 
Q1--Q2---R1
  |   |--R2
  |
  |-Q3--R3
      |-Q4--R4
          |-R5
 
Q1
{
 Q2
 {
  R1
  R2
 }
 Q3
 {
  R3
  Q4
  {
   R4
   R5
  }
 }
}
 
l'indentation en moins
et voilà.
 
Pour lire, tu procède récursivement de la même manière:
tu lis un noeud, puis, s'il y a des accolades après, son fils droit puis son fils gauche (oui/non)
 
Et là tout marche.

Reply

Marsh Posté le 13-06-2001 à 00:52:27    

ok ,  merci pour ton aide.
Je vais essayer de coder tout ça demain
 
ciao !

Reply

Marsh Posté le 13-06-2001 à 00:55:11    

output c'est tu écris dans un fichier
input, c'est tu lis d'un fichier

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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

© 2018 Forum. All Rights Reserved.