|
|
|
|
Bonjour!
Je suis en train de faire un programme gerant une base de donnée grace a des fichiers textes!
J'ai deux fichier txt un avec les données et l'autre avec un index:
Le fichier index se present comme ceci:
c'est un arbre binaire de recherche avec pour caracteristique de structure:
une clé.
un nom.
la clé du fils gauche.
la clé du fils droit.
J'ai donc créé un fonction ajouté dans l'arbre seul contrainte ne pas utiliser
de tableau:
Voici ma fonction:
void index_bd::ajouter_bd(char* nom)
{
int nbrec;
int resultat;
bool end=false;
index temp,temp2,temp_index,nouvau;
FILE* findex_temp;
fseek(findex,0,SEEK_END);
nbrec=ftell(findex)/sizeof(index);
temp2.cle=nbrec+1;
strcpy(temp2.nom,nom);
temp2.cle_gauche=0;
temp2.cle_droite=0;
fseek(findex,0,SEEK_SET);
fread(&temp,sizeof(index),1,findex);
while (end!=true)
{
if(feof(findex))
{end=true;}
else{
resultat=strcmp(nom,temp.nom);
if(resultat<0)
{
if(temp.cle_gauche!=0)
{
fseek(findex,(temp.cle_gauche-1)*sizeof(index),SEEK_SET);
fread(&temp,sizeof(index),1,findex);
}
else
{
cout<<"le pere est"<<temp.cle;
temp.cle_gauche=temp2.cle;
end=true;
}
}
else
{
if (temp.cle_droite!=0)
{
fseek(findex,(temp.cle_droite-1)*sizeof(index),SEEK_SET);
fread(&temp,sizeof(index),1,findex);
}
else
{
cout<<"voici le pere"<<temp.cle<<endl;
temp.cle_droite=temp2.cle;
end=true;
}
}
}
}
fseek(findex,0,SEEK_SET);
findex_temp=fopen("findex_temp.txt","w");
fread(&temp_index,sizeof(index),1,findex);
while(fread(&temp_index,sizeof(index),1,findex)!=0)
{
if(temp_index.cle!=temp.cle)
{
fwrite(&temp_index,sizeof(index),1,findex_temp);
}
else{
fwrite(&temp,sizeof(index),1,findex_temp);
}
};
fwrite(&temp2,sizeof(index),1,findex_temp);
fclose(findex);
fclose(findex_temp);
findex=fopen("index.txt","w");
findex_temp=fopen("findex_temp.txt","r");
fseek(findex_temp,0,SEEK_SET);
while(fread(&nouvau,sizeof(index),1,findex_temp)!=0)
{
fwrite(&nouvau,sizeof(index),1,findex);
}
fclose(findex);
fclose(findex_temp);
cout<<temp.cle_droite<<endl;
cout<<temp.cle_gauche<<endl;
}
class index_bd
{
private:
FILE *findex;
struct index{
int cle;
char nom[40];
int cle_gauche;
int cle_droite;
};
index* gauche;
index* droite;
public:
index_bd();
~index_bd();
void afficher_bd();
void ajouter_bd(char nom[40]);
void supprimer_bd(int);
void rechercher_bd();
};
while(fread(&temp_index,sizeof(index),1,findex)!=0)
{
if(temp_index.cle!=temp.cle)
{
fwrite(&temp_index,sizeof(index),1,findex_temp);
}
else{
fwrite(&temp,sizeof(index),1,findex_temp);
}
};
Haha lol ;o) Bon je viens de regarder un peu ton programme et il y a quelques trucs qui me choquent.
|
Je suis tout a fait d'accord avec toi!
|
Oula pas d'adresse sur un forum malheureux ;o) Et moi msn ce n'est pas possible déontologiquement désolé ;o)
id_noeud id_noeud_fils_gauche id_noeudfils_droit nom Fichier 2 : des infos sur chaque nom au format nom numero adresse. Voici le genre de classes que je te propose :
#include <string>
class noeud{
public:
noeud * fils_gauche;
noeud * fils_droit;
std::string nom;
noeud(std::string nom0):nom(nom0){ }
};
class arbre{
private:
unsigned int id_dispo; //un id pour un nouveau noeud
protected:
noeud * racine;
public:
inline unsigned int get_id_dispo(){
return id_dispo;
}
arbre():id_dispo(0),racine(0){}
~arbre{
supprimer_noeud(racine);
}
void detruire_noeud(noeud *n);
noeud * trouver_noeud(unsigned int id); //pour trouver l'adresse d'un noeud connaissant son identiifant
bool ajouter_noeud(noeud *pere,std::string nom_fils);
bool supprimer_noeud(unsigned int idnoeud);
};
Trois opérations possibles : - mise à jour facile il suffit de corriger la bonne ligne ;) - suppression -> supprimer le noeud de l'arbre et ses fils : void arbre::supprimer_noeud(noeud * n){
if (n.fils_gauche){
supprimer_noeud(n.fils_gauche);
}
if (noeud.fils_droit){
supprimer_noeud(n.fils_gauche);
}
//supprimer le noeud n du fichier
//....
}
- ajout Bon là j'ai pas trop capté comment tu ajoutais ? Tu précise le noeud père ? Que se passe-t'il s'il a dejà deux fils ?
bool arbre::ajouter_noeud(noeud * pere,std::string fils){
if (!pere.fils_gauche){
pere.fils_gauche=noeud(fils,get_dispo());
id_dispo++;
//Ecrire dans les fichiers....
return true;
}
if (!pere.fils_droit){
pere.fils_droit=noeud(fils,get_dispo());
id_dispo++;
//Ecrire dans les fichiers....
return true;
}
return false; //déjà deux fils !!
} |
...
|
Merci bien pour toutes ces infos!!
fseek(findex,0,SEEK_SET);
findex_temp=fopen("findex_temp.txt","w");
fread(&temp_index,sizeof(index),1,findex);
while(fread(&temp_index,sizeof(index),1,findex)!=0)
{
if(temp_index.cle!=temp.cle)
{
fwrite(&temp_index,sizeof(index),1,findex_temp);
}
else{
fwrite(&temp,sizeof(index),1,findex_temp);
}
};
fwrite(&temp2,sizeof(index),1,findex_temp);
fclose(findex);
fclose(findex_temp);
findex=fopen("index.txt","w");
findex_temp=fopen("findex_temp.txt","r");
fseek(findex_temp,0,SEEK_SET);.
la mise a jour dans le fichier,probleme que je n'ai su resoudre qu'en utilisant un tableau et recopiant le contenu dans le fichier! De plus d'autres erreurs y sont comme appration de plusieurs lignes identiques et toujours aucun mise a jour du pere!! Car pour ce qui est de la mise a jour comme tu le dis: "il suffit de corriger la bonne ligne" et bien justement c'est celle la qui me pose probleme depuis a peu pres 8h ce matin! Je vais essayer de la trouver mais dans le cas contraire je pense opter pour la solution la moins contraignante la structure! Je te remercie pour ces explications |
Merci bien pour toutes ces infos!!
|
Bon si j'avais su j'aurais fait la structure bien avant et puis le but final c'est que ca marche!!!!
c:\windows\temp\class.cpp(414) : fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1786) Please choose the Technical Support command on the Visual C++ Help menu, or open the Technical Support help file for more information Error executing cl.exe. main.exe - 1 error(s), 0 warning(s) Mais bon ca au moins ca vient pas du projet!!! Je te remercie pour le temps passé a me lire et a me repondre! MErci a toi |
Le pb c'est que sans structure on va en chier ;o) Je suis même pas sûr que ce soit faisable... Le C++ ce n'est pas de la bidouille (bien au contraire) et le programme c'est une chose, enseigner nimp c'en est une autre ;o) A ta place je repartirais sur des bases saines (ie structures+ objet comme je t'ai expliqué) même si ce n'est pas comlètement du goût de ton prof ;) Au moins tu auras une ébauche d ece qu'est le c++ ;o)
|
Je n'ai pas regardé dans le détail, mais je pense que si tu recherche les deux dans ton fichier, puis que tu en supprime un, le deuxième risque de se décaler dans ton fichier d'où le problème. A ta place je ferais une fonction récursive comme indiqué plus haut.
|
Merci!
|
En fait ce que je ne comprend pas c'est que lorsque je lance mes fonctions:
int max=obtenir_plus_grand_fils(temp.cle_gauche); int min=obtenir_plus_petit_fils(temp.cle_droite); j'obtiens des valeurs pour la cle lorsqu'il lit le buffer de l'ordre de 2408 etc...: fseek(findex,(n-1)*sizeof(index),SEEK_SET); fread(&buffer,sizeof(index),1,findex); Des fois il passe impecable mais desfois il me sorts des valeurs comme celle ci au debug ce qui parait vraiment etonnant vu que je ne change pas le fichier et que normalement la lecture est la meme. J'ai donc tenté de me repositionné au debut du fichier avant de me positionner a la bonne ligne mais rien n'y change le nombre reste aléatoire....ce qui alors devient genant voir completement farfelue pour la suite et entraine une boucle infini dans la suite de la fonction |
Pour supprimer tes noeud fils il faut commencer par le bas et remonter progressivement (la fameuse descente recursive dont je parlais pus haut), comme ça tu es sûr de ne pas en oublier. Si ta procédure est clean pour un fils quelle que soit sa position dans le fichier, et que tu réinitialises ton pointeur de fichier correctement après une suppression, il ne doit pas y avoir de problème.
|
J'ai donc resolu tous mes problemes mon programme est disponible la:
|
Et moi je le decompresse comment ton ace si je suis sous linux ;o) Fais-moi un rar/zip/tar.gz/tar.bz2 mais pas un ace, un 7zip, un ice ou je ne sais quel format exotique ;o) Espèce de Windows corporate ^^
|
Hihi désolé pour le type de fichier mais j'aime bience qui est exotique ;)
|
J'arrive pas à le décompresser ;o)(il ne suffit pas de changer l'extension, hein ;o)) Fais-moi un beau zip fait à partir de tes fichiers d'origine.
|
Bon ca devrait etre bon normalement le rar doit etre bien fait
|
C'est pas mal pour une première fois ;) Même très bien ;) Encore félicitations ^^
int f(int x1,y1); Le code est mis dans un .cpp qui inclue le .h (.hpp même). Le seul cas où le code est dans les hpp c'est pour les templates... 2)Pour les interfaces, essaye d'utiliser la syntaxe doxygen. Voici les balises de base : /** * \brief un résumé du rôle de ma fonction. * \param x1 le premier paramètre * \param y1 le deuxième paramètre * \return Ca retourne un truc ;o) * \todo Les améliorations à apporter à la fonction * \sa Les fichiers ou regarder pour plus de détails */ Comme ça tu générera directement ce que tu as en fait mis dans ton rapport ;o) En latex, en html la total ^^ 3) Il aurait été bien de faire un makefile. Je te laisse regarder les tutos sur le Net... C'est un outil très pratique ;) 4) Ton code est bien indenté, lisible, et aéré donc ça c'est bien. Qui plus est tu as fait l'effort de faire des modules et ça c'est bien . Excellente continuation, et j'espère que tu passeras sous linux ;) |