IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Indexer un texte


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Indexer un texte
    Bonjour,

    En m'aidant de vos réponses, j'ai écris un programme servant à indexer un texte.
    Le but étant de trouver les lignes dans lesquelles apparait un mot.

    Les deux première fonctions du menu fonctionnent (test de l'ouverture et affichage) mais le reste non (indexation, recherche du mot, suppression de l'index)...
    Je n'ai pas d'erreurs de compilation.

    Je ne comprends pas d'où viennent les erreurs, et je dois avouer que je perds patience...

    Si vous pouviez m'aider je vous en serais très reconnaissant.

    Je poste tout le code, je doute que les erreurs viennent des fonctions d'allocation ou d'affichage mais on ne sait jamais.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #define TAILLE 200
     
     
    // *********
    // Structure
    // *********
     
     
    //structure d'une ligne de l'index
    struct Ligne
    {
        char* ligne;        //tableau de caractères
        int numero;         //numéro de la ligne
        struct Ligne* suiv; //pointeur sur la structure Ligne suivante
    };
    typedef struct Ligne* liste;
     
     
    // ***************
    // Fonctions liste
    // ***************
     
     
    //crée une liste vide
    liste nouvelle_liste()
    {
        liste l;
        l = malloc (sizeof(*l));
        l->ligne = "";
        l->numero = 0;
        l->suiv = l;
        return l;
    }
     
     
    //supprime la liste de la mémoire
    void supprime_liste(liste l)
    {
        liste tmp, a_detruire;
        tmp = l->suiv;
        while(tmp != l)
        {
            a_detruire = tmp;
            tmp = tmp->suiv;
            free(a_detruire);
        }
        free(l);
        puts ("\nL'index a ete supprime\n");
    }
     
     
    //ajoute une ligne à la fin de la liste
    liste ajoute_liste (liste l, char* _ligne, int _numero)
    {
        liste nouvelle_ligne;
        nouvelle_ligne = malloc (sizeof(*nouvelle_ligne));
        nouvelle_ligne->ligne = (char*) malloc (sizeof(strlen(_ligne) +1));
     
        if (nouvelle_ligne->ligne != NULL)
        {
            strcpy(nouvelle_ligne->ligne, _ligne);
        }
        nouvelle_ligne->numero = _numero;
        l->suiv = nouvelle_ligne;
     
        return nouvelle_ligne;
    }
     
     
    //affiche la liste
    void affiche_liste (liste l)
    {
        liste actuel;
        puts("\nListe de l'index :\n");
        for (actuel = l->suiv; actuel != l; actuel = actuel->suiv)
        {
            printf("%d) %s\n", actuel->numero, actuel->ligne);
        }
    }
     
     
    // *****************
    // Fonctions fichier
    // *****************
     
     
    //affiche le texte
    void affiche_fichier (FILE* fichier)
    {
        int caractere_actuel = 0;
     
        caractere_actuel = fgetc (fichier);
        while (caractere_actuel != EOF)
        {
            printf("%c", caractere_actuel);
            caractere_actuel = fgetc(fichier); //on passe au caractère suivant
        }
    }
     
     
    //indexe le texte
    char* indexe_fichier (FILE* fichier)
    {
        char chaine[TAILLE]; //tableau temporaire
        char* p = NULL;
     
        if (fichier != NULL && fgets (chaine, TAILLE, fichier) != NULL) //lire une ligne
        {
            //supprimer le caractère de fin de ligne
            p = strchr (chaine, '\n');
            if (p != NULL) *p = '\0';
     
            p = malloc (strlen (chaine) +1); //allouer la quantité nécessaire
            if (p != NULL) strcpy (p, chaine); //pour copier la chaine si l'allocation a réussi
        }
        return p; // retourne la chaine ou NULL
    }
     
     
    //remplit la liste
    liste remplit_liste (FILE* fichier)
    {
        liste liste_remplie = NULL;
        char* ligne;
        int numero = 1;
        do
        {
            ligne = indexe_fichier(fichier); //récupérer les chaînes
            if (ligne != NULL)
            {
                liste_remplie = ajoute_liste(liste_remplie, ligne, numero); //les mettre dans la liste
            }
            numero++;
        }
        while(ligne != NULL); //tant qu'il y en a
        return liste_remplie;
    }
     
     
    //cherche les lignes du texte où se trouve le mot
    void trouve_mot (liste l, char* mot)
    {
        int trouve = 0;
        char* present;
        liste actuel;
     
        for (actuel = l->suiv; actuel != l; actuel = actuel->suiv)
        {
            //on cherche la première occurence de mot dans actuel->ligne
            present = strstr(actuel->ligne, mot);
            if(present != NULL)
            {
                printf(" ligne %d\n", actuel->numero);
                trouve = 1;
            }
        }
        if (trouve == 0)
        {
            printf("Le mot %s n'a pas ete trouve", mot);
        }
    }
     
    // *********
    // Menu
    // *********
     
     
    int menu()
    {
        int choix = 0;
        do
        {
            puts("\nMenu :\n");
            puts("1) tester l'ouverture d'un fichier : COMMENCER PAR CETTE OPERATION\n");
            puts("2) afficher un fichier\n");
            puts("3) indexer un fichier : OPERATION OBLIGATOIRE AVANT LE 4)\n");
            puts("4) chercher un mot dans le fichier indexe (les lignes ou il apparait)\n");
            puts("5) supprimer l'index pour indexer un autre fichier\n");
            puts("6) quitter le programme (supprimera l'index)\n");
            puts("\nVotre choix ? (entre 1 et 6)");
            scanf("%d", &choix);
            puts("\n");
     
            if (choix < 1 || choix > 6)
                puts("Ce choix n'existe pas ! Veuillez ecrire un chiffre entre 1 et 6\n");
        }
        while (choix < 1 || choix > 6);
        return choix;
    }
     
     
    // *********
    // Main
    // *********
     
     
    int main ()
    {
        FILE* fichier = NULL;
        char nom_fichier[50] = {0};
        char mot[20] = {0};
        liste _liste;
     
        while (1)
        {
            switch (menu())
            {
     
     
                //choix du fichier à tester
            case 1:
                puts("Chemin du fichier a ouvrir (sous la forme textes/nom_du_fichier.txt : ");
                scanf("%s", nom_fichier);
                fichier = fopen (nom_fichier, "r"); //mode lecture seule
    //si on peut ouvrir le fichier
                if (fichier != NULL)
                {
                    printf("\nLe fichier %s peut etre ouvert\n", nom_fichier);
                    fclose(fichier);
                }
    //sinon
                else
                {
                    printf("\nImpossible d'ouvrir le fichier %s\n", nom_fichier);
                }
                puts("\n");
                break;
     
     
    //affichage du fichier
            case 2:
                puts("Chemin du fichier a afficher (sous la forme textes/nom_du_fichier.txt : ");
                scanf("%s", nom_fichier);
                fichier = fopen (nom_fichier, "r"); //mode lecture seule
                puts("\n");
                if (fichier != NULL)
                {
                    affiche_fichier(fichier);
                    fclose(fichier);
                }
                else
                {
                    printf("\nImpossible d'afficher le fichier %s\n", nom_fichier);
                }
                puts("\n");
                break;
     
     
    //indexation du fichier
            case 3:
                puts("Chemin du fichier a indexer (sous la forme textes/nom_du_fichier.txt : ");
                scanf("%s", nom_fichier);
                fichier = fopen (nom_fichier, "r"); //mode lecture seule
                puts("\n");
                if (fichier != NULL)
                {
                    indexe_fichier(fichier);
                    _liste = remplit_liste(fichier);
                    affiche_liste(_liste);
                    fclose(fichier);
                }
                else
                {
                    printf("\nImpossible d'indexer le fichier %s\n", nom_fichier);
                }
                puts("\n");
                break;
     
     
    //recherche d'un mot dans l'index
            case 4:
                puts("Mot a rechercher : ");
                scanf("%s", mot);
                puts("\n");
                trouve_mot(_liste, mot);
                break;
     
     
    //suppression de l'index
            case 5:
                supprime_liste(_liste);
                break;
     
     
    //suppression de l'index et fin du programme
            case 6:
                supprime_liste(_liste);
                exit(-1);
                break;
     
            }
        }
        return 0;
    }

  2. #2
    Inactif  


    Homme Profil pro
    Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Inscrit en
    Décembre 2011
    Messages
    9 026
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Loire (Rhône Alpes)

    Informations professionnelles :
    Activité : Doctorant sécurité informatique — Diplômé master Droit/Économie/Gestion
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2011
    Messages : 9 026
    Par défaut
    Bonjour,

    Pour que nous puissions t'aider plus efficacement, pourrais-tu nous décrire ces erreurs ?

  3. #3
    Membre éclairé
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2011
    Messages
    274
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2011
    Messages : 274
    Par défaut
    Salut, tout d'abord change
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l = malloc (sizeof(*l))
    Dans la fonction nouvelle_liste() en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    l = (liste) malloc (sizeof(struct Ligne));
    En effet malloc retourne un pointeur de type void* que tu dois convertir dans le bon type. De plus le sizeof(l) que tu faisais était inapproprié car étant un pointeur il n'aurait pas eu la bonne taille (tu aurais pu cependant mettre sizeof(*l))

    C'est la même chose pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    nouvelle_ligne = (liste)malloc (sizeof(*nouvelle_ligne));
    et pour
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    p = (char*) malloc (strlen (chaine) +1);
    Je n'ai pas fait attention aux fuites de mémoire il se peut qu'il y en ait mais ça tu le verras après

  4. #4
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    En effet malloc retourne un pointeur de type void* que tu dois convertir dans le bon type.
    On n'est pas en C++ et la conversion void* <-> pointeur est implicite. Donc l = malloc (sizeof(*l)) est parfaitement correct et peut aussi s'écrire l = malloc (sizeof *l)

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 062
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef struct Ligne* liste;
    Je trouve que ça nuit inutilement à la lecture du code.

    Avant faudra allouer de la mémoire pour écrire dans tes cases de char.
    Et ensuite on utilise strcpy pour assigner une valeur à une chaîne de caractères.

    Soit c'est moi qui est pas pigé, soit c'est toi, moi je l'aurais pointé vers NULL.

    Occupe toi déjà de ta fonction nouvelle_liste() et teste avant de continuer d'autres fonctions si elle est fonctionnelle, si oui tu peux continuer, sinon on continue sur cette fonction.

    Excuse moi, mais entre ta structure qui s'appelle Ligne et ta chaîne qui s'appelle ligne, tu cherches le mal...

    En ce qui concerne la structure, j'ai toujours trouvé plus simple de comprendre ce type de structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    typedef struct
    {
        char *ligne;
        int numero;
        struct Element *suivant;
    } Element;
     
    typedef struct
    {
        Element *first;
        int taille;
    } Liste;
     
    Liste *nouvelle_liste(void);

  6. #6
    Membre Expert Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Par défaut
    Bonjour

    je ne souhaite pas intervenir sur le détail du code (pour résumer, je pense que tu t'attaques trop vite à trop gros compte tenu de tes connaissances) mais sur le fond.

    Indexer "quelque chose" sert, après, à ne pas parcourir ce "quelque chose" dans tous les sens et à aller plus directement aux endroits intéressants en gagnant du temps.

    Dans la mesure où

    Citation Envoyé par 1Désix
    Le but étant de trouver les lignes dans lesquelles apparait un mot.
    découper un texte en lignes et mettre ces lignes dans une liste (c'est ce que tu veux faire) n'est d'aucune utilité. Tu vas devoir, de toute façon, parcourir tout ton texte (toutes les lignes de ton texte) pour rechercher le mot.

    Tes efforts sont louables mais ne brûle pas les étapes !

Discussions similaires

  1. Erreur sur champ text pour un index Full-Text
    Par Steph82 dans le forum Outils
    Réponses: 5
    Dernier message: 06/01/2011, 14h08
  2. Index full text sur champs multiples
    Par manu_71 dans le forum Outils
    Réponses: 6
    Dernier message: 22/02/2007, 00h41
  3. reconstruction d'index de texte intégral
    Par zarbiman dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 14/12/2005, 08h23
  4. Comment indexer du texte ?
    Par Batou dans le forum SQL Procédural
    Réponses: 4
    Dernier message: 27/07/2005, 03h38
  5. MSDE et index de texte integral
    Par Pasiphae dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 18/11/2004, 19h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo