Partage
  • Partager sur Facebook
  • Partager sur Twitter

Probleme table de hachage

Sujet résolu
    19 février 2020 à 22:44:15

    Bonjour, je viens d'apprendre comment fonctionnait une table de hachage et j'ai écrit un petit code. Je pense que j'ai du m’emmêler les pinceaux quelque part. Je suis pas encore trop à l'aise avec ça. Le but de mon programme :

    - Je récupère des infos sur des personnes dans un fichier txt (nom, prenom, age) :

    Meunier
    Jean
    17
    
    // c'est ce que j'ai dans mon fichier texte actuellement

    - je les stocke dans un tableau de type structure "Personne", voici la structure :

    struct Personne
    {
        char* nom;
        char* prenom;
        int age;
    };
    
    typedef struct Personne Personne;

    Je l'initialise :

    void init_struct(Personne **list)
    {
        for(int i=0;i<TAB_SIZE;i++)
        {
            list[i] = malloc(sizeof(*list[i]));
            if(list[i] == NULL) exit(EXIT_FAILURE);
        }
    
    }

    Pour trouver l'index du tableau j'utilise la fonction de hachage suivante :

    int hachage(char *chaine)
    {
        int i = 0, nombreHache = 0;
    
        for (i = 0 ; chaine[i] != '\0' ; i++)
        {
            nombreHache += chaine[i];
        }
        nombreHache %= TABLE_SIZE; // TAB_SIZE vaut 100 actuellement
    
        return nombreHache;
    }

    Voici la fonction qui permet de récupérer les infos du fichier texte, puis de les enregistrer dans le tableau :

    void restoreDB(Personne **list)  // "DB" comme DataBase
    {
        char temp[3][20], temp2[50];  // temp[3] car il y a le nom, le prenom et l'age.
        int hach = 0;
        FILE* file = NULL;
        file = fopen("database.txt","r+");
        if(file == NULL) exit(EXIT_FAILURE);
    
        while(!feof(file))
        {
            for(int j=0;j<NB_ELEMENTS_STRUCT;j++)
            {
                fgets(temp[j],20,file);
                for(int i=0;temp[j][i]!='\0';i++)
                    if(temp[j][i] == '\n') temp[j][i] = '\0';
            }
            printf("\n%d",atoi(temp[2]));
    /////////////////////////////////////// Ces lignes collent le nom et le prenom dans temp2, ex:"Jean Meunier"
            strcpy(temp2,temp[0]);
            strcat(temp2," ");
            strcat(temp2,temp[1]);
    ////////////////////////////////////////
            hach = hachage(temp2); // Egale à 39
            //printf("%s, hachage = %d",temp2,hach);
            list[hach]->nom = temp[0];
            list[hach]->prenom = temp[1];
            list[hach]->age = atoi(temp[2]);
            printf("\n%s",list[hach]->nom);
        }    
        fclose(file);
    }

    - Ensuite, j'essaye de retrouver puis d'afficher les informations sur une personne :

    void disp_DB(char* name, Personne **list)
    {
        int hach = hachage(name);
    printf("\n%s",list[hach]->nom); printf("\n%s",list[hach]->prenom); printf("\n%d\n",list[hach]->age); }

    Problème : Le nom  et le prenom ne s'affiche pas. Seul l'age s'affiche correctement.

    Voici mon main() :

    int main()
    {
        Personne* tab[TABLE_SIZE];
    
        init_struct(tab);
        restoreDB(tab);  // Il y a un "printf("\n%s",list[hach]->nom);" à la fin de la fonction qui affiche bien le nom "Meunier" en console.
    //hach = 39, dans les deux cas. disp_DB("Jean Meunier",tab); // Le "printf("\n%s",list[hach]->nom);" n'affiche pas cette fois le nom "Meunier" en console.
    // Ce sont des caracteres aleatoires qui s'affichent à la place. De même pour le prenom free_struct(tab); return 0; }

    J'ai fait un printf du nom à deux endroits different pour un meme nom de famille ("Meunier"), et ça n'affiche pas du tout la meme chose. Le deuxieme printf qui s'effectue dans la fonction disp_DB() affiche des caractere au hasard :

    Meunier
    Ç@  //printf qui devrait afficher le nom
    ╠ a
    17

    (Par contre l'âge s'affiche correctement, "17").

    Honnêtement je suis pas très sûr de certains trucs. J'aimerai savoir si le paramètre de mes fonctions "Personne **liste" est correct. Est ce que c'est correct de l’écrire de cette manière ? Dans le main, j'ai déclarer mon tableau de cette façon "Personne* tab[TABLE_SIZE];" (TABLE_SIZE = 100).

    Si quelqu'un a une idée concernant les deux printf? Pourquoi l'un des deux n'affiche pas le bon nom ?

    Voila, je pense que j'ai du faire tout de même quelques erreurs (peut être beaucoup, j'espère pas quand même :-°) donc si votre oeil d'expert en voit, n'hésité pas.

    Je vous remercie par avance.

    -
    Edité par MrTeed 20 février 2020 à 23:48:32

    • Partager sur Facebook
    • Partager sur Twitter
    MrTeed
      20 février 2020 à 23:36:21

      Il y aurait pas une confusion entre sizeof et strlen ?

      -
      Edité par michelbillaud 20 février 2020 à 23:36:49

      • Partager sur Facebook
      • Partager sur Twitter
        20 février 2020 à 23:37:40

        J'ai finalement trouvé la solution... J'avais fait une erreur dans ma structure :

        typedef struct
        {
            char* nom;
            char* prenom;
            int age;
        }Personne;

        Enfaite il fallait écrire :

        typedef struct
        {
            char nom[20];
            char prenom[20];
            int age;
        }Personne;

        Après avoir fait cela, j'ai finalement eu 2 erreurs :

                list[hach]->nom = temp[0];
                list[hach]->prenom = temp[1];

        Il fallait remplacer ces deux lignes par :

                strcpy(list[hach]->nom,temp[0]);
                strcpy(list[hach]->prenom,temp[1]);

        Forcement, ce sont des char il fallait utiliser strcpy... Erreur d'inattention, j'espère que ce topic servira a quelqu'un un jour. Sur ce, je vous laisse...:D

        Bye.


        EDIT : 

        michelbillaud a écrit:

        Il y aurait pas une confusion entre sizeof et strlen ?

        -
        Edité par michelbillaud il y a 4 minutes

        Tu veux dire dans cette fonction là ?

        void init_struct(Personne **list)
        {
            for(int i=0;i<TABLE_SIZE;i++)
            {
                list[i] = malloc(sizeof(*list[i])); // je crois que j'aurais du mettre sizeof(list[i])?
                if(list[i] == NULL) exit(EXIT_FAILURE);
            }
         
        }

        Je crois que j'aurais du mettre malloc(sizeof(list[i])) ? En enlevant l'etoile devant le list. Ou alors peut etre mettre malloc(sizeof(Personne)) ? C'est limite plus simple comme ça enfaite je crois.


        D'ailleurs, je me demandais : Est-il juste de liberer la memoire de mon tableau de cette manière?

        void free_struct(Personne **list)
        {
            for(int i=0;i<TABLE_SIZE;i++)
                free(list[i]);
        }






        -
        Edité par MrTeed 20 février 2020 à 23:55:39

        • Partager sur Facebook
        • Partager sur Twitter
        MrTeed

        Probleme table de hachage

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown