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

  FORUM HardWare.fr
  Programmation

  sauvegarde dans un fichier C++

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

sauvegarde dans un fichier C++

n°39211
jibix
Posté le 12-06-2001 à 22:38:46  profilanswer
 

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

mood
Publicité
Posté le 12-06-2001 à 22:38:46  profilanswer
 

n°39215
jibix
Posté le 12-06-2001 à 22:45:17  profilanswer
 

help please !

n°39220
janoscoder
Posté le 12-06-2001 à 23:06:39  profilanswer
 

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

n°39221
janoscoder
Posté le 12-06-2001 à 23:10:44  profilanswer
 

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à

n°39223
jibix
Posté le 12-06-2001 à 23:14:02  profilanswer
 

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)

n°39225
janoscoder
Posté le 12-06-2001 à 23:19:08  profilanswer
 

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!

n°39226
janoscoder
Posté le 12-06-2001 à 23:22:01  profilanswer
 

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

n°39229
janoscoder
Posté le 12-06-2001 à 23:24:56  profilanswer
 

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).

n°39232
jibix
Posté le 12-06-2001 à 23:28:43  profilanswer
 

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...

n°39235
janoscoder
Posté le 12-06-2001 à 23:32:20  profilanswer
 

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.

mood
Publicité
Posté le 12-06-2001 à 23:32:20  profilanswer
 

n°39237
jibix
Posté le 12-06-2001 à 23:33:56  profilanswer
 

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;
        };
   };

n°39247
janoscoder
Posté le 12-06-2001 à 23:45:08  profilanswer
 

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.

n°39250
jibix
Posté le 12-06-2001 à 23:51:34  profilanswer
 

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 !)

n°39251
jibix
Posté le 12-06-2001 à 23:53:40  profilanswer
 

ç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

n°39256
janoscoder
Posté le 13-06-2001 à 00:15:16  profilanswer
 

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.

n°39258
janoscoder
Posté le 13-06-2001 à 00:26:37  profilanswer
 

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***********

n°39262
jibix
Posté le 13-06-2001 à 00:43:44  profilanswer
 

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)

n°39263
jibix
Posté le 13-06-2001 à 00:45:29  profilanswer
 

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

n°39264
janoscoder
Posté le 13-06-2001 à 00:48:20  profilanswer
 

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.

n°39266
jibix
Posté le 13-06-2001 à 00:52:27  profilanswer
 

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

n°39267
janoscoder
Posté le 13-06-2001 à 00:55:11  profilanswer
 

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

mood
Publicité
Posté le   profilanswer
 


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

  sauvegarde dans un fichier C++

 

Sujets relatifs
[ASP] envoyer un fichier attaché à un mail avec CDONTScomment creer un fichier d'aide ?!
Pb de fichier sous PHP....[XML/XSL] un<br/> dans le fichier XML, comment avoir <br> en html ?
[PHP] fonctions entrée/sortie, et sauvegarde de page automatique...Cherche un hebergeur PHP permettant upload de fichier via formulaire
[PHP] Comment faire reference a un fichier php d'un autre site ???[C++] Problème avec le chargement des données d'un fichier
[PHP Toujours] fin d'un fichierFichier texte et VB 6
Plus de sujets relatifs à : sauvegarde dans un fichier C++


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