Pb eof en C++ le dernier element est lu 2 fois :(

cs_panini21 Messages postés 11 Date d'inscription jeudi 21 août 2003 Statut Membre Dernière intervention 31 janvier 2007 - 30 déc. 2003 à 15:10
D1m3x Messages postés 402 Date d'inscription samedi 28 décembre 2002 Statut Membre Dernière intervention 21 juillet 2005 - 1 janv. 2004 à 14:32
salut a tous

voila g un prog qui permet de creer une 'bibliotheque de jeux'
a savoir :

les renseignement du jeu sont le prix, le nom, la descriptiopn et d'un mot clef pour le recherche facile.
(-> utilisation de surcharge d'operateur)

quand on ajoute un jeu , celui ci est directement stocker dans un fichier .txt pour ne pas perdre.

le probleme vien de l'affichage , en effet le dernier element est lu 2 fois ...

le travail est fait a 90 % ...
reste juste cette fameuse boucle
while (!f_entre.eof) {...}
qui s'arrete trop tard ...

merci a ceux qui voudron bien me donner la solution :)

voici le prog :

#include
#include <math.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <fstream.h>

#define max 30

/************************************************************************/
class CJeu
{private:
char titre[max],type[max];
float prix;
char mot_cle[max];
// cdate date_achat;
public :
Cjeu(void);
void set_titre(char * );
void set_type(char * );
void set_prix(float);
void set_mot_cle(char * );
char * get_titre(char * );
char * get_type(char * );
float get_prix(void);
char * get_mot_cle(char * );
// surcharge des flots d'entrer sorties standart
friend ostream & operator << (ostream&,CJeu);
friend istream & operator >> (istream&,CJeu &);
// surcharge des flots fichier
friend ofstream & operator << (ofstream&,CJeu);
friend ifstream & operator >> (ifstream&,CJeu&);
};
/***********************************************************************/

CJeu :: Cjeu(void)
{strcpy(titre,"");
strcpy(type,"");
strcpy(mot_cle,"");
prix=0;
}

void CJeu :: set_titre(char * ch)
{strcpy(titre,ch);}

void CJeu :: set_type(char * ch)
{strcpy(type,ch);}

void CJeu :: set_prix(float val)
{prix = val;}

void CJeu :: set_mot_cle(char * ch)
{strcpy(mot_cle,ch);}

char * CJeu :: get_titre(char * ch )
{strcpy(ch,titre);
return ch;
}

char * CJeu :: get_type(char * ch)
{strcpy(ch,type);
return ch;
}

float CJeu :: get_prix(void)
{return prix;}

char * CJeu :: get_mot_cle(char * ch)
{strcpy(ch,mot_cle);
return ch;
}


ostream & operator << (ostream&s, CJeu j)
{s<<"titre : "<<j.titre<<endl;
s<<"type : "<<j.type<<endl;
s<<"prix : "<<j.prix<<endl;
s<<"mot cle : "<<j.mot_cle<<endl;
return s;
}

istream & operator >> (istream&s, CJeu&j)
{cout<<"titre ? "; s>>j.titre;
cout<<"type ? "; s>>j.type;
cout<<"prix ? "; s>>j.prix;
cout<<"mot cle ? "; s>>j.mot_cle;
return s;
}

ofstream & operator << (ofstream&s, CJeu j)
{s<<j.titre<<endl;
s<<j.type<<endl;
s<<j.prix<<endl;
s<<j.mot_cle<<endl;
return s;
}

ifstream & operator >> (ifstream&s, CJeu&j)
{s>>j.titre;
s>>j.type;
s>>j.prix;
s>>j.mot_cle;
return s;
}


/*******************************************************************************/

class Cbiblio
{private :
char nom_fichier[max];
public :
Cbiblio ( void );
Cbiblio ( char * );
void ajout(char *);
void recherche_mot_cle(void);
void recherche_titre (void);
void affiche (char*);
// on surcharge de << pour ostream;
void suppression (void);
};

/*******************************************************************************/

Cbiblio :: Cbiblio ( void )
{strcpy(nom_fichier," ");}

Cbiblio :: Cbiblio ( char * ch)
{strcpy(nom_fichier,ch);}

void Cbiblio :: ajout(char * nom)
{ofstream f_sortie;
CJeu j;
cout<<" nouveau jeu :"<<endl;
// ouverture du fichier en ajout
f_sortie.open(nom,ios :: app);
// saisie du jeu
cin >> j; // surcharge sur istream
// ecriture du fichier
f_sortie << j; // surcharge sur ofstream
// fermeture
f_sortie.close();
}


void Cbiblio :: recherche_mot_cle(void)
{ifstream f_entre;
CJeu j;
char chaine[max],ch[max];
int test=0;
cout<<"donner le mot clé a chercher : ";
cin>> chaine;
cout<<endl;
f_entre.open (nom_fichier , ios :: in);
while (!f_entre.eof() && !test)
{ f_entre >> j; // surcharge sur ifstream
if (strcmp(chaine,j.get_mot_cle(ch))==0) test=1;
}
f_entre.close();
if (test)
{cout<<" le jeu a ete effectifvement trouver"<<endl;
cout << j; // surcharge sur ostream
}
else
{cout<<" le jeu n'existe pas dans la bibliotheque"<<endl;}
}

void Cbiblio :: recherche_titre (void)
{ifstream f_entre;
CJeu j;
char chaine[max],ch[max];
int test=0;
cout<<"donner le titre a chercher : ";
cin>> chaine;
cout<<endl;
f_entre.open (nom_fichier , ios :: in);
while (!f_entre.eof() && !test)
{ f_entre >> j; // surcharge sur ifstream
if (strcmp(chaine,j.get_titre(ch))==0) test=1;
}
f_entre.close();
if (test)
{cout<<" le jeu a ete effectivement trouver"<<endl;
cout << j; // surcharge sur ostream
}
else
{cout<<" le jeu n'existe pas dans la bibliotheque"<<endl;}
}

void Cbiblio :: affiche (char * nom_fich)
{ifstream f_entre;
CJeu j;
f_entre.open (nom_fich , ios :: in);
do{cout<<" jeu :"<<endl;
f_entre >> j; // surcharge sur ifstream
cout << j; // surcharge sur ostream
cout << endl;
}while( !f_entre.eof());
f_entre.close();
}

int copiefichier (char * dest , char * srce)
// copie de fichier srce dans dest
// renvoi 1 si ok, 0 sinon
{
ifstream fi(srce, ios::in|ios::binary);
if (!fi) return 0; // source impossible a lire
ofstream fo (dest, ios::out|ios::binary);
if (!fo) return 0;
char tampon;
while ( fo && fi.get(tampon))
fo.put(tampon);
return fo.good() && fi.eof();
}

void Cbiblio :: suppression (void)
{Cbiblio temporaire("temp.txt");
ifstream f_entre;
ofstream f_sortie;
CJeu j;
int test=0,boucle=0,ok=0;
char chaine[max],ch[max];
cout<<" donner le titre du jeu a suprimer ";
cin >> chaine;
cout<<endl;
f_sortie.open("temp.txt",ios :: app);
f_entre.open ("bibliotheque.txt" , ios :: in);
while (!f_entre.eof())
{
f_entre >> j; // surcharge sur ifstream
if (strcmp(chaine,j.get_titre(ch))) f_sortie << j;
}
f_entre.close();
f_sortie.close();
ok=copiefichier ("bibliotheque.txt" , "temp.txt");
if (ok) cout<<"supression effectuer"<<endl;
else cout<<"po marcher"<<endl;
}

/***********************************************************************/
int menu(void)
{int ch;
cout<<endl<<endl;
cout<<" 0.quitter"<<endl;
cout<<" 1.insertion d'un nouveau jeu"<<endl;
cout<<" 2.suppression d'un jeu"<<endl;
cout<<" 3.affichage"<<endl;
cout<<" 4.recherche d'un jeu par son titre"<<endl;
cout<<" 5.recherche d'un jeu par son mot cle"<<endl;
//cout<<" 6.supprimer le fichier jeu"<<endl;
cout<<" donner votre choix : ";
cin>>ch;
return ch;
}


void main()
{int choix;
Cbiblio fichier("bibliotheque.txt");
cout<<endl;
do
{choix=menu();
switch(choix)
{case 1 : fichier.ajout("bibliotheque.txt");
break;
case 2 : fichier.suppression();
break;
case 3 : fichier.affiche("bibliotheque.txt");
break;
case 4 : fichier.recherche_titre();
break;
case 5 : fichier.recherche_mot_cle();
break;
}
}
while (choix !=0);
}

5 réponses

cs_vieuxLion Messages postés 455 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 6 avril 2004 8
30 déc. 2003 à 15:33
oui
ce serait mieux si tu avais fait

while( !f_entre.eof()){cout<<" jeu :"<<endl;
f_entre >> j; // surcharge sur ifstream
cout << j; // surcharge sur ostream
cout << endl;
};

attention aux fautes d'orthographes
ton constructeur CJeu::Cjeu n'en est pas un (case sensitive)
0
cs_panini21 Messages postés 11 Date d'inscription jeudi 21 août 2003 Statut Membre Dernière intervention 31 janvier 2007
30 déc. 2003 à 17:57
en effet la boucle while( !f_entre.eof()){...}
est mieu approprier , mais le probleme reste le meme !!

a l'affichage le dernier element est toujours affiché 2 fois
:(((

pour faire le test rapidement :
lancer l'appli...

taper : '1' (ajout )
taper le titre : 'aaa' ('aaa' convien parfaitement , lol)
taper le type : 'aaa'
taper le prix : '123' (metre un int sinon ca bug)
taper le mot clef : 'aaa'

taper : '3' (affichage)

et la , a mon grand malheur , ca affiche 2 fois des 'aaa' et des '123' : le dernier element a ete recopier 2 fois :(

pour le constructeur ,
"ton constructeur CJeu::Cjeu n'en est pas un (case sensitive)"
je ne connais pas le terme le terme "case sensitive"
pouvez vous brievement me m'expliquer ?

je vous remerci pour vos reponces ;)
0
cs_vieuxLion Messages postés 455 Date d'inscription samedi 26 octobre 2002 Statut Membre Dernière intervention 6 avril 2004 8
30 déc. 2003 à 18:39
salut
pour les problèmes de flux d'entrée,
tu devrais regarder le source suivant :
http://www.cppfrance.com/code.aspx?ID=10394
... et peut être aussi
http://www.cppfrance.com/code.aspx?ID=10298

ou alors (en attendant), essaie ceci :
void Cbiblio :: affiche (char * nom_fich)
{ifstream f_entre;
CJeu j;
f_entre.open (nom_fich , ios :: in);
while( f_entre >> j)
{cout<<" jeu :"<<endl;
cout << j; // surcharge sur ostream
cout << endl;
};

le "case sensitive" veux simplement dire qu'il faut faire attention aux Majuscules/minuscules
et ne pas confondre CJeu avec Cjeu !
0
cs_panini21 Messages postés 11 Date d'inscription jeudi 21 août 2003 Statut Membre Dernière intervention 31 janvier 2007
30 déc. 2003 à 20:31
comme ca peut etre simple des fois l'informatique ....

en efet la boucle while( f_entre >> j) convient
ce qui resoud mon probleme merci

mais aussi
http://www.cppfrance.com/code.aspx?ID=10394
http://www.cppfrance.com/code.aspx?ID=10298

sont particulierement util pour les pb du genre :
taper le prix : '123' (metre un int sinon ca bug)

....
merci bien vieuxlion et bonne fete a tous ;)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
D1m3x Messages postés 402 Date d'inscription samedi 28 décembre 2002 Statut Membre Dernière intervention 21 juillet 2005 1
1 janv. 2004 à 14:32
taper le prix : '123' (metre un int sinon ca bug)

ca ne peux pas bugger! alors soit tu dois gérer une exveptio (C++), soit tu vérifie si c'est bien un int, je suis pas sur mais je crois que la fonction isalnum( ) le permet je suis plus sur sinon va voir sur la MSDN.

[DmX]
0
Rejoignez-nous