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
|
#include <stdio.h> // pour FILE, stderr, les fontions stream, printf(), fprintf() et gets()
#include <stdlib.h> // pour exit()
#include <string.h> // pour strtok() et strdup()
#define DEBUG if (1) fprintf
//Déclaration
typedef char * str;
typedef long unsigned int idx;
typedef struct node {void *car; struct node *cdr;} node, *list;
typedef struct ndex{str mot; list refs;} ndex;
//Défintions et initialisations de variables globales
const str split_chars ="(., -;:'\t\n!<>)"; //Une séquence de caractères comportant des délimiteurs nécessaires à la fonction strtok()
enum{
nil,
max_mots = 10000, //Nombre maximum de mots
max_refs = 16, //Nombre maximum de référence par mots
max_ligne = 256, //Nnombre maximum de lignes dans le fichier
max_stoplist= 13, //Nombre maximum de mots dans la stoplist
tampon = 32, //Zone de mémoire temporaire nécessaire dans la fonction recuperer_stoplist()
};
typedef enum {
False,True} bool;
idx mot_libre = 0; //Variable qui indique la prochaine cellule vide du vecteur mots
ndex mots[max_mots];
str mots_stoplist[max_stoplist];
//Les prototypes des fonctions :
void usage(str, str);
void indexe(str, idx);
int indice(str);
bool pareil(str, str);
void ajoute_mot(idx, str, idx);
void ajoute_ref(idx, idx);
void dump(idx);
FILE * ouvrir_fichier(const str);
void fermer_fichier(FILE *, str);
void recuperer_stoplist();
int compare(const void*, const void*);
list cons(void *car, list L);
void putlist(list);
int main (int argc, const str argv[]){
// Cette fonction ouvre un fichier, ajoutes chaque mot dans un vecteur de mots
// en le reliant à ses références et son numéro de lignes
if (argc != 2)
usage(argv[0], "Usage : <nom du programme> <nom du fichier>\n");
FILE * flux = ouvrir_fichier(argv[1]);
char ligne[max_ligne];
idx x = 0;
recuperer_stoplist();
while (fgets(ligne, max_ligne, flux))
indexe(ligne, ++x);
fermer_fichier(flux, argv[1]);
qsort(mots, mot_libre, sizeof(ndex), compare);
dump(mot_libre);
return 0;
}
int compare(const void *E1, const void *E2){
return strcasecmp(* (char * const *) E1, * (char * const *) E2);
}
FILE * ouvrir_fichier(const str nom_fichier){ //Ouverture d'un fichier en mode lecture avec vérification
FILE * fichier = fopen(nom_fichier, "r");
if (!fichier)
usage(nom_fichier,"Echec lors de l'ouverture du fichier, consulter la documentation utilisateur\n");
return fichier;
}
void fermer_fichier(FILE * flux, str nom_fichier){ // Fermeture d'un fichier avec vérification
if (fclose(flux))
usage(nom_fichier, "Echec lors de la fermeture du fichier, consulter la documentation utilisateur\n");
}
void recuperer_stoplist(){ // Ouvre un fichier contenant la stoplist et enregister les mots dans un vecteur
FILE * stoplist = ouvrir_fichier("stoplist.data");
int lu;
for (idx i = 0; lu != EOF; ++i){
char sas[tampon];
lu = fscanf(stoplist,"%s", sas);
if (i > max_stoplist)
usage("stoplist.data", "Le nombre maximum de mots autorisé est dépassé\n");
mots_stoplist[i] = strdup(sas);
}
fermer_fichier(stoplist, "stoplist.data");
}
void usage(str nom_fichier, str message){ //Affiche un message d'erreur
perror(nom_fichier);
fprintf(stderr, message);
exit(1);
}
void indexe(str ligne, idx ref){
//Extrait les mots de l'argument ligne, si ils existent,
//vérifie si les mots existent dans le vecteur mots grâce à indice(mot)
//et envoie chaque mot soit vers la fonction ajoute_mot()
//ou soit vers ajoute_ref() suivant leur existance ou non dans les tables
str mot = strtok(strdup(ligne), split_chars);
while (mot){
int x = indice(mot);
if (x < 0)
ajoute_mot(mot_libre, mot, ref);
else
ajoute_ref(x, ref);
mot = strtok(NULL, split_chars);
}
}
int indice(str mot){ //retourne l'indice d'un mot déja présent dans mots[maxmots] ou -1 s'il est inexistant.
idx x;
for (x = 0; mots[x].mot; ++x)
if (pareil(mot, mots[x].mot))
return x;
return -1;
}
bool pareil(str x, str y){ // return Vraie que x et y sont similaire sinon retourne faux.
return strcasecmp(x, y) ? False : True;}
void ajoute_mot(idx x, str mot, idx ref){ // ajoute le mot dans le vecteur mots à l'indice x correspondant
for(int i = 0 ; i < max_stoplist; ++i){
if (pareil(mot, mots_stoplist[i]))
return;
}
mots[x].mot = mot;
idx *ptr_ref = &ref;
mots[x].refs = cons(ptr_ref, nil);
++mot_libre;
}
void ajoute_ref(idx x, idx ref){ //Ajoute une référence
idx * ptr_ref = &ref;
//ajoute une référence dans la matrice refs[max_mots][max_ref]
if(mots[x].refs->car != ptr_ref) mots[x].refs = cons(ptr_ref, mots[x].refs);
}
void dump(idx k){
// Affichage des mots, de leur lignes et du nombre de références associés
idx x = 0;
while(mots[x].mot){
printf("%s :", mots[x].mot);
putlist(mots[x].refs);
printf("\n");
++x;
}
}
list cons(void *car, list L){ // Implémentation d'un cons
list new = malloc(sizeof(node));
idx * ptr_car = car;
if (!new) usage ("","cons : manque de RAM");
new -> car = *ptr_car;
new -> cdr = L;
return new;
}
void putlist(list L){ //Affichage d'une liste
if (!L) return; //nil : fin de ligne
putlist(L -> cdr);
printf(" %li ", (idx) L -> car);
} |
Partager