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

  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 012
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    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 012
    Points : 23 145
    Points
    23 145
    Par défaut
    Bonjour,

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

  3. #3
    Membre habitué
    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
    Points : 176
    Points
    176
    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 éminent sénior
    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
    Points : 13 926
    Points
    13 926
    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)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    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 : 3 813
    Points : 7 102
    Points
    7 102
    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);
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  6. #6
    Membre expérimenté 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 : 59
    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
    Points : 1 481
    Points
    1 481
    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 !
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  7. #7
    Invité
    Invité(e)
    Par défaut
    Re-bonjour,

    Comme vous avez pu le remarquer je débute, il est donc normal que je fasse des erreurs. Je me rends compte maintenant que j'ai posté mon code un peu trop hâtivement. Je me laisse quelques jours pour revoir tout ça calmement et je reviendrais avec des questions bien précises.

    Quelques explications :

    Je n'ai pas alloué de mémoire pour l->ligne de la fonction nouvelle_liste parce que je ne voulais pas de caractères. Mais j'avais oublié le caractère de fin de chaîne '\0'.

    Si je souhaite avoir "", je dois écrire ceci ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l->ligne = malloc (sizeof(char));
        strcpy(l->ligne, "");
    J'ai retouché le code depuis mon post, et plusieurs oublis de ma part ont été rectifiés.
    Par exemple, j'avais laissé la bibliothèque <ctype.h> sans l'utiliser, parce que j'avais choisi de ne traiter que les caractères en minuscule (à la fois pour l'indexation et la recherche de mots). J'ai depuis supprimé la fonction concernée mais je pense qu'elle est nécessaire. Ça évitera des problèmes de recherche. Si je cherche le mot "maison" et que le texte contient "Maison", je ne serais pas gêné. Il manquait aussi du code dans ajoute_liste.

    La fonction nouvelle_liste crée une élément repère qui me servira à parcourir la liste.
    Si j'ajoute un élément, la liste aura la forme :
    repère - élément1 - repère

    Étant donné que j'avais choisi de faire une liste simplement chaînée, ajouter un deuxième élément donnera la forme :
    repère - élément2 - élément1 - repère

    Je pense donc changer et utiliser une chaîne doublement chaînée, pour respecter l'ordre des lignes du texte (pour l'affichage des lignes où est présent un mot, le programme commencera par la première ligne et non la dernière).

    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 !
    Vous avez raison, l'idéal serait d'avoir un programme optimal, mais comme vous dites, je préfère ne pas brûler les étapes. Je me soucierai de la qualité de l'indexation plus tard (ne prendre que les mots longs, ne pas s'occuper des lignes vides, etc). Sans oublier que c'est un bon entraînement.

  8. #8
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 813
    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 : 3 813
    Points : 7 102
    Points
    7 102
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l->ligne = malloc (sizeof(char));
        strcpy(l->ligne, "");
    Oui vaguement car il y a le test d'allocation à ne pas oublier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (l->ligne == NULL)
    {
        fprintf(stderror, "Erreur allocation");
        exit(EXIT_FAILURE);
    }
    Sinon comme dis précédemment, réfléchi bien à ta structure, c'est important pour la suite du boulot...
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  9. #9
    Invité
    Invité(e)
    Par défaut
    A vrai dire, pour la structure j'ai comparé deux possibilités et j'ai choisi la deuxième.

    - la plus efficace :
    Avoir une liste contenant toutes les lettres de l'alphabet, à chaque lettre est attribué une sous-liste contenant tout les mots du texte commençant par cette lettre.
    Chercher un mot revient à regarder sa première lettre et explorer la sous-liste correspondante.

    - la plus facile :
    Avoir une liste contenant toutes les lignes du texte.
    On se contente de regarder si un mot fait partie d'une ligne, puis on passe à la ligne suivante.

    Je préfère donc commencer par la plus facile.

  10. #10
    Invité
    Invité(e)
    Par défaut
    Après quelques jours au calme, je reviens avec ceci :

    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #define TAILLE 100
     
     
    // *********
    // Structure
    // *********
     
     
    //structure d'un element de la liste
    struct Element
    {
        char* ligne;          //tableau de caracteres
        int numero;           //numéro de la ligne
        struct Element* prec; //pointeur sur l'element precedent
        struct Element* suiv; //pointeur sur l'element suivant
    };
    typedef struct Element* liste;
     
     
    // ***************
    // Fonctions liste
    // ***************
     
     
    //cree un element repere utilise comme depart et arrivee de la liste
    liste nouvelle_liste()
    {
        liste l;
        l = malloc (sizeof(*l));
        l->ligne = (char*) malloc (sizeof(char) * strlen("repere") +1);
        strcpy (l->ligne, "repere");
        if (l->ligne == NULL)
        {
            fprintf(stderr, "Erreur allocation");
            exit(EXIT_FAILURE);
        }
        l->numero = 0;
        l->prec = l;
        l->suiv = l;
        return l;
    }
     
     
    //supprime la liste de la memoire
    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); //suppression du repere
        puts ("\nL'index a ete supprime\n");
    }
     
     
    //ajoute un element a la fin de la liste
    liste ajoute_liste (liste l, char* _ligne, int _numero)
    {
        liste element;
        element = malloc (sizeof(*element));
        element->ligne = (char*) malloc (sizeof(char) * strlen(_ligne) +1);
        strcpy (element->ligne, _ligne);
        if (element->ligne == NULL)
        {
            fprintf(stderr, "Erreur allocation");
            exit(EXIT_FAILURE);
        }
        element->numero = _numero;
        element->prec = l->prec; //le precedent du nouvel element est le dernier element
        element->suiv = l; //le suivant du nouvel element est l'element repere
        l->prec->suiv = element; //le suivant du dernier element est le nouvel element
        l->prec = element; //le dernier element est maintenant le nouvel element
        return element;
    }
     
     
    //affiche la liste : ligne + son numéro
    void affiche_liste (liste l)
    {
        liste actuel;
        puts("\nListe :\n");
        for (actuel = l->suiv; actuel != l; actuel = actuel->suiv)
        {
            printf("%d) %s\n", actuel->numero, actuel->ligne);
        }
    }
     
     
     
    // *****************
    // Fonctions fichier
    // *****************
     
     
    //convertir les caractères majuscules d'une chaine en minuscule
    void minuscule (char* chaine)
    {
        int i;
        for (i = 0; chaine[i] != '\0'; i++)
            if (isupper(chaine[i])) //si le caractère est majuscule
                chaine[i]= tolower(chaine[i]); //le passer en minuscule
    }
     
     
    //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
        }
    }
     
     
    //extrait les lignes du texte et les place dans la liste
    liste remplit_liste (liste a_remplir, FILE* fichier)
    {
        int numero = 1;
        char chaine[TAILLE] = "";
        char* p = NULL;
     
        while (fgets (chaine, TAILLE, fichier) != NULL)
        {
            //suppression du caractère de fin de ligne
            p = strchr (chaine, '\n');
            if (p != NULL) *p = '\0';
            p = (char*) malloc (sizeof(char) * strlen (chaine) +1);
            if (p != NULL) strcpy (p, chaine); //copie de la chaîne
            minuscule (p); //convertit les caractères majuscules en minuscules
     
            ajoute_liste(a_remplir, p, numero); //met la chaîne dans la liste
            numero++;
        }
        return a_remplir;
        fclose(fichier);
    }
     
     
    //cherche les lignes du texte où se trouve un mot
    void trouve_mot (liste l, char* mot)
    {
        int trouve = 0;
        char* present;
        liste actuel = NULL;
     
        for (actuel = l->suiv; actuel != l; actuel = actuel->suiv)
        {
            //on cherche la première occurence du 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);
        }
    }
     
     
    int main()
    {
     
        FILE* fichier = NULL;
        char nom_fichier[50] = {0};
        //choix du fichier a tester
        puts("Chemin du fichier a ouvrir (sous la forme nom_du_fichier.txt) : ");
        scanf("%s", nom_fichier);
        fichier = fopen (nom_fichier, "r"); //mode lecture seule
        puts("\n");
     
     
        if (fichier != NULL)
        {
            liste l = nouvelle_liste();
            printf("%d) %s\n", l->numero, l->ligne); //affiche le repere
            l = remplit_liste(l, fichier);
            affiche_liste(l);
     
            char mot[TAILLE];
            puts("Mot a rechercher :");
            scanf("%s", mot);
            minuscule (mot);
            puts("\n");
            trouve_mot(l, mot);
        }
     
        else
        {
            printf("\nImpossible d'ouvrir le fichier %s\n", nom_fichier);
        }
     
        return 0;
     
    }
    En testant avec le texte suivant :

    Texte de TEST
    .
    **
    .....texte....
    abababababtestabababab.
    sfsfsfs test sdsdsdsdssdsd.
    apapappapaptexteazazazazaza.
    zazazazazza texte azazazazaz.
    tes
    text
    qsqsdq, test texte
    TEXT TES.....
    TEXTE TEST.....

    FIN DU TEXTE.
    Le programme m'affiche ceci :

    0) repere

    Liste :

    1) texte de test
    2) .
    3) **
    4) .....texte....
    5) abababababtestabababab.
    6) sfsfsfs test sdsdsdsdssdsd.
    7) apapappapaptexteazazazazaza.
    8) zazazazazza texte azazazazaz.
    9) tes
    10) text
    11) qsqsdq, test texte
    12) TEXT TES.....
    13) TEXTE TEST.....
    14)
    15) FIN DU TEXTE.

    Mot a rechercher :
    texte

    ligne 1
    ligne 4
    ligne 7
    ligne 8
    ligne 11
    ligne 13
    ligne 15
    La recherche fonctionne.

    Suite à vos réponses, je me demande pourquoi écrire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            fprintf(stderr, "Erreur allocation");
            exit(EXIT_FAILURE);
    et non :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            puts("Erreur allocation");
            exit(-1);
    Dernière modification par Invité ; 20/01/2013 à 14h37.

  11. #11
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 189
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 189
    Points : 17 141
    Points
    17 141
    Par défaut
    Dans le premier cas, c'est pour écrire dans le flux d'erreur plutot que le flux de sortie standard.
    Dans le second, il vaut mieux renvoyer la constante prévue pour ce cas, elle est standard.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  12. #12
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    A noter que la plupart du temps, stdin et stderr sont connectées à l'écran et que cela a le même effet pour l'utilisateur. En revanche, tu peux rediriger stdin et stderr vers des fichiers et c'est dans des cas comme ça que tu vois l'avantage de séparer les 2 flux dans ton code.

    Tu peux par exemple faire ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fprintf(stderr, "Erreur allocation dans la fonction xxxx");
    fprintf(stderr, "Errno : %d : %s", errno, strerror(errno));
     fprintf(stdin, "Desole, l'application a rencontre une erreur et doit se terminer");
    Et avoir un message à l'écran pour l'utilisateur et un fichier de logs exploitables pour un développeur pour comprendre l'origine du crash de l'application.

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