sauvegarde dans un fichier C++ - Programmation
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
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à
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)
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!
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...
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).
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...
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.
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;
};
};
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.
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 !)
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
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.
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
lapinpoils:oui),(pattes:4),(herbivore:oui)
moucheailes:oui)
chatpoils:oui),(pattes:4),(herbivore:non)
chienpoils: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.
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 ?