Commit 1e4b8b9c3e5da1050b05ebab15fe5ca2dfd3a029
1 parent
674eb93a
Code complet commenté
Showing
4 changed files
with
212 additions
and
201 deletions
Show diff stats
... | ... | @@ -10,8 +10,8 @@ int main(int argc, char *argv[]) |
10 | 10 | { |
11 | 11 | init_pgrm(); |
12 | 12 | Node tree = NULL; |
13 | - int error = 0; | |
14 | - int correct = 0; | |
13 | + int error = 0; // compteur d'erreurs | |
14 | + int correct = 0; // compteur de corrections effectuées | |
15 | 15 | FILE* fp_lib; |
16 | 16 | FILE* fp_txt; |
17 | 17 | |
... | ... | @@ -21,8 +21,8 @@ int main(int argc, char *argv[]) |
21 | 21 | return EXIT_FAILURE; |
22 | 22 | } |
23 | 23 | |
24 | - fp_lib = fopen(argv[argc-2], "r"); | |
25 | - fp_txt = fopen(argv[argc-1], "r+"); | |
24 | + fp_lib = fopen(argv[argc-2], "r"); // ouverture du fichier bibliothèque en mode lecture | |
25 | + fp_txt = fopen(argv[argc-1], "r+"); // ouverture du fichier à analyser en mode lecture/écriture | |
26 | 26 | |
27 | 27 | if(fp_lib==NULL || fp_txt==NULL) |
28 | 28 | { |
... | ... | @@ -30,22 +30,24 @@ int main(int argc, char *argv[]) |
30 | 30 | return EXIT_FAILURE; |
31 | 31 | } |
32 | 32 | |
33 | - init_tree(&tree); | |
34 | - read_lib(fp_lib, &tree); | |
35 | - read_txt(fp_txt, &tree, &error, &correct); | |
33 | + init_tree(&tree); // initialisation de l'arbre indexé | |
34 | + read_lib(fp_lib, &tree); // lecture de la bibliothèque | |
35 | + read_txt(fp_txt, &tree, &error, &correct); // analyse du fichier et corrections éventuelles | |
36 | 36 | |
37 | 37 | // Si vous souhaitez imprimer l'arbre indexé complet : |
38 | 38 | //char word[MAX] = ""; |
39 | 39 | //print_tree(tree, 0, word); |
40 | 40 | |
41 | + // Impression du nombre d'erreurs | |
41 | 42 | if(error<2) printf("Dans le texte %s, %d mot n'est pas dans le dictionnaire %s.\n", argv[argc-1], error, argv[argc-2]); |
42 | 43 | else printf("Dans le texte %s, %d mots ne sont pas dans le dictionnaire %s.\n", argv[argc-1], error, argv[argc-2]); |
43 | 44 | |
45 | + // Impression du nombre de corrections | |
44 | 46 | if(correct<2) printf("%d a été corrigé.\n", correct); |
45 | 47 | else printf("%d ont été corrigés.\n", correct); |
46 | 48 | |
47 | - free_tree(&tree); | |
48 | - fclose(fp_lib); | |
49 | + free_tree(&tree); // Libération de l'espace mémoire | |
50 | + fclose(fp_lib); // Fermeture des fichiers texte | |
49 | 51 | fclose(fp_txt); |
50 | 52 | return EXIT_SUCCESS; |
51 | 53 | } | ... | ... |
texte.txt
... | ... | @@ -6,7 +6,7 @@ The ant and the cicada |
6 | 6 | |
7 | 7 | In the summer, the ant families were very busy. They knew that in the winter they would have to stay in their anthill. They wanted to have enough food for the whole winter. |
8 | 8 | |
9 | - While the ants worked hard, the cicadas didn't do anything. They sang and danced all day. When they were hungry, they coud fly to the farm and get something to eat. | |
9 | + While the ants worked hard, the cicadas didn't do anything. They sang and danced all day. When they were hungry, they could fly to the farm and get something to eat. | |
10 | 10 | |
11 | 11 | One day the cicadas were singing and dancing. They saw a long line of ants bringing food to their anthill. The cicadas said, Stop, my silly friends. It's a very nice day. Come and dance with us. The ants said, Don't you know about winter? If you don't work now, you'll have trouble later. |
12 | 12 | |
... | ... | @@ -24,3 +24,7 @@ The ant and the cicada |
24 | 24 | |
25 | 25 | |
26 | 26 | |
27 | + | |
28 | + | |
29 | + | |
30 | + | ... | ... |
... | ... | @@ -27,7 +27,7 @@ void init_tree(Node* Tree) |
27 | 27 | if(is_empty_tree(*Tree)) |
28 | 28 | { |
29 | 29 | *Tree = malloc(sizeof(node)); |
30 | - (*Tree)->letter = 7; // | |
30 | + (*Tree)->letter = 7; // caractère sans utilité | |
31 | 31 | (* Tree)->endWord = false; |
32 | 32 | for(int i=0; i<NB_CARAC; i++) |
33 | 33 | (*Tree)->next[i] = NULL; // initialisation du tableau 'next' à un tableau de pointeurs NULL |
... | ... | @@ -35,13 +35,11 @@ void init_tree(Node* Tree) |
35 | 35 | } |
36 | 36 | |
37 | 37 | // Détermine l'indice de rangement dans le tableau 'next' du caractère 'letter' |
38 | -int find_caract_indice(char letter) // Ne fonctionne pas pour les caractères accentués | |
38 | +int find_caract_indice(char letter) | |
39 | 39 | { |
40 | - //printf("__%d__\n", letter); | |
41 | 40 | if(letter>=97 && letter<=122) return letter-'a'; |
42 | 41 | if(letter>=65 && letter<=90) return letter-'A'; |
43 | 42 | if(letter == 39) return letter-13; // l'apostrophe est placée en 27ème position |
44 | - //if(letter>=192) {printf("%d", letter-166); return letter-166;} //-192+26 | |
45 | 43 | } |
46 | 44 | |
47 | 45 | // Fonction d'ajout d'un mot 'word' dans la structure 'tree' de type 'arbre indexé' |
... | ... | @@ -52,38 +50,34 @@ void add_in_tree(Node Tree, char word[]) |
52 | 50 | Node Tree2 = Tree; |
53 | 51 | while(word[j] != '\0') // on parcourt tout le mot 'word' |
54 | 52 | { |
55 | - /*if(is_leaf(Tree2)) // a retirer | |
56 | - printf("empty\t");*/ | |
57 | 53 | char letter = word[j]; |
58 | - ind = find_caract_indice(letter); | |
59 | - if(Tree2->next[ind]!=NULL) // si le pointeur du tableau 'next' corresdant au caractère lu n'est pas NULL, on s'insère dans cette 'branche' de l'arbre indexé et on continue avec le caractère suivant | |
54 | + ind = find_caract_indice(letter); // on récupère l'indice de rangement de 'letter' | |
55 | + | |
56 | + if(Tree2->next[ind]!=NULL) // si le pointeur du tableau 'next' correspondant au caractère lu n'est pas NULL, on s'insère dans cette 'branche' de l'arbre indexé et on continue avec le caractère suivant | |
60 | 57 | { |
61 | 58 | Tree2 = Tree2->next[ind]; |
62 | - /* printf("%c %d\t", letter, ind); | |
63 | - printf("okA %d\n", j);*/ | |
64 | 59 | } |
65 | 60 | else // sinon, on ajoute une nouvelle cellule de type 'struct node' et on y insère les informations concernant le caractères |
66 | 61 | { |
67 | 62 | Node new = NULL; |
68 | 63 | new = malloc(sizeof(node)); |
69 | - new->letter = letter; // le caractère | |
70 | - for(int i=0; i<NB_CARAC; i++) // un tableau de pointeurs NULL | |
64 | + | |
65 | + new->letter = letter; | |
66 | + for(int i=0; i<NB_CARAC; i++) | |
71 | 67 | { |
72 | 68 | new->next[i]=NULL; |
73 | 69 | } |
74 | 70 | new->endWord = false; |
71 | + | |
75 | 72 | Tree2->next[ind] = new; // on fait pointé le tableau du caractère précédent vers cette cellule (vers ce caractère) |
76 | - if(!(Tree2->endWord)) // si le caractère n'est pas un caractère de fin, on le met à 'false' -> UTILITE ? | |
73 | + if(!(Tree2->endWord)) // si le caractère précédent n'est pas un caractère de fin, on lui donne la valeur 'false' | |
77 | 74 | Tree2->endWord = false; |
78 | 75 | Tree2=Tree2->next[ind]; // on se place au niveau du caractère suivant dans l'arbre indexé |
79 | - /*printf("%c %d\t", letter, ind); | |
80 | - printf("okB %d\n", j);*/ | |
81 | 76 | } |
82 | 77 | j++; |
83 | 78 | if(word[j]=='\0') // si le caractère suivant est la fin de la chaîne, on dit que le caractère précédent est un caractère de fin |
84 | 79 | Tree2->endWord = true; |
85 | 80 | } |
86 | - //printf("ok\n"); | |
87 | 81 | } |
88 | 82 | |
89 | 83 | // Fonction qui détermine si le caractère est un caractère de fin de mot (espace, ',', ';', '.', etc..) |
... | ... | @@ -103,168 +97,172 @@ char max_index(char word[]) |
103 | 97 | return index; |
104 | 98 | } |
105 | 99 | |
106 | -void scan_word(Node Tree, char word[], int* error, FILE* fp_txt, int* correct) // si un mot démarre juste après un caractère de fin, la fonction ne lit pas les mots séparément | |
100 | +// Fonction qui scanne les mots du fichier à vérifier et les analyse | |
101 | +void scan_word(Node Tree, char word[], int* error, FILE* fp_txt, int* correct) | |
107 | 102 | { |
108 | - bool endWord = false; | |
109 | - bool stop = false; | |
110 | - int ind = 0; | |
111 | - int indice; | |
103 | + bool endWord = false; // true : le caractère est un caractère de fin, false : le caractère n'est pas un caractère de fin | |
104 | + bool stop = false; // permet de ne pas compte 2 fois certaines erreurs | |
105 | + int ind = 0; // indice dans le mot 'word' | |
106 | + int indice; // indice de rangement de letter dans le tableau 'next' | |
112 | 107 | char letter; |
113 | 108 | Node Tree2 = Tree; |
114 | - while(!is_end_caract(word[ind])) | |
109 | + while(!is_end_caract(word[ind])) // si 'word[ind]' n'est pas un caractère de fin | |
115 | 110 | { |
116 | 111 | stop = false; |
117 | 112 | letter = word[ind]; |
118 | - indice = find_caract_indice(letter); | |
113 | + indice = find_caract_indice(letter); // récupération de l'indice de rangement | |
119 | 114 | |
120 | - if(Tree2 != NULL && Tree2->next[indice]!=NULL) | |
115 | + if(Tree2 != NULL && Tree2->next[indice]!=NULL) // si l'arbre n'est pas vide et que la case correspondant à la lettre dans l'arbre n'est pas vide | |
121 | 116 | { |
122 | - ind++; | |
123 | - Tree2 = Tree2->next[indice]; | |
117 | + ind++; // on passe à la lettre suivante | |
118 | + Tree2 = Tree2->next[indice]; // on se met dans la case de la lettre qui vient d'être vérifiée | |
124 | 119 | endWord = Tree2->endWord; |
125 | 120 | } |
126 | 121 | else |
127 | 122 | { |
128 | - add_error(error, word, ind, Tree2, fp_txt, correct); | |
129 | - //printf("%d\n", ind); | |
130 | - ind = max_index(word); | |
131 | - //printf("%d\n", ind); | |
123 | + add_error(error, word, ind, Tree2, fp_txt, correct); // si l'abre est vide ou que la case de l'arbre correspondant à la lettre est vide, on ajoute une erreur | |
124 | + ind = max_index(word); // on se place à la fin du mot pour ne pas continuer de vérifier ses lettres | |
132 | 125 | stop = true; |
133 | 126 | endWord = false; |
134 | 127 | } |
135 | 128 | } |
136 | - if(!endWord && !stop) | |
129 | + if(!endWord && !stop) // si un mot manque d'au moins une lettre (endWord == false alors qu'on a atteint la fin du mot à scanner) | |
137 | 130 | { |
138 | - add_error(error, word, ind, Tree2, fp_txt, correct); | |
131 | + add_error(error, word, ind, Tree2, fp_txt, correct); // on ajoute une erreur | |
139 | 132 | } |
140 | 133 | } |
141 | 134 | |
135 | +// Ajoute une erreur, donne le type d'erreur et lance le processus de correction | |
142 | 136 | void add_error(int* error, char word[], int index, Node Tree, FILE* fp_txt, int* correct) |
143 | 137 | { |
144 | 138 | (*error)++; |
145 | - if(index==0) | |
139 | + if(index==0) // si la première lettre n'est pas reconnu, on ne propose pas de correction | |
146 | 140 | { |
147 | 141 | printf("Le mot '%s' ne correspond à aucun mot du dictionnaire.\n\n", word); |
148 | 142 | return; |
149 | 143 | } |
150 | - else if(index<strlen(word)) | |
144 | + else if(index<strlen(word)) // si l'index d'erreur n'est pas le dernier indice du mot, on a une faute dans le mot | |
151 | 145 | printf("Il y a une erreur dans le mot '%s', au caractère %c d'incide %d.\n", word, word[index], index); |
152 | - else | |
146 | + else // sinon l'erreur a lieu à la fin du mot | |
153 | 147 | printf("Il manque au moins une lettre au mot '%s'.\n", word); |
154 | - make_correction(word, index, Tree, fp_txt, correct); | |
148 | + make_correction(word, index, Tree, fp_txt, correct); // processus de correction | |
155 | 149 | } |
156 | 150 | |
157 | -void make_correction(char word[], int index, Node Tree, FILE* fp_txt, int* correct) // gestion des caractères de fin | |
151 | +// Lance le processus de correction, avec les différentes initialisations | |
152 | +void make_correction(char word[], int index, Node Tree, FILE* fp_txt, int* correct) | |
158 | 153 | { |
159 | - correction liste = NULL; | |
160 | - init_correction(&liste); | |
161 | - char end; | |
162 | - bool testEnd; | |
163 | - testEnd = detect_end_caract(&end, word); | |
164 | - int longueur = strlen(word); | |
165 | - Node Tree2 = Tree; | |
166 | - word[index-1]='\0'; | |
167 | - printf("\n"); | |
168 | - char words[MAX] = ""; | |
169 | - make_tree_correct(Tree2, 0, words, word, liste); | |
170 | - choice_word(liste, fp_txt, end, longueur, correct, testEnd); | |
171 | - free(liste); // VALGRIND ??? | |
154 | + correction liste = NULL; // crée une liste contigüe qui contiendra les propositions de correction | |
155 | + init_correction(&liste); // initalise cette liste | |
156 | + char end; // permet de stocker un éventuel caractère de fin (',', ';', '?', etc..) | |
157 | + bool testEnd; // true si le mot possede un caractère de fin, false sinon | |
158 | + testEnd = detect_end_caract(&end, word); | |
159 | + int longueur = strlen(word); | |
160 | + Node Tree2 = Tree; | |
161 | + word[index-1]='\0'; // on coupe le mot avant l'erreur | |
162 | + printf("\n"); | |
163 | + char words[MAX] = ""; // chaine de caractères permettant le stockage des différentes lettres pouvant composer les mots de correction | |
164 | + make_tree_correct(Tree2, 0, words, word, liste); // rempli la liste chainée avec les propositions de correction | |
165 | + choice_word(liste, fp_txt, end, longueur, correct, testEnd); // permet le choix du mot de correction et lance le processus de remplacement | |
166 | + free(liste); | |
172 | 167 | } |
173 | 168 | |
169 | +// Détermine si le mot word possède un caractère de fin et le renvoie si c'est le cas | |
174 | 170 | bool detect_end_caract(char* end, char word[]) |
175 | 171 | { |
176 | - if(is_end_caract(word[strlen(word)-1])) | |
177 | - { | |
178 | - *end = word[strlen(word)-1]; | |
179 | - return true; | |
180 | - } | |
181 | - return false; | |
172 | + if(is_end_caract(word[strlen(word)-1])) | |
173 | + { | |
174 | + *end = word[strlen(word)-1]; | |
175 | + return true; | |
176 | + } | |
177 | + return false; | |
182 | 178 | } |
183 | 179 | |
180 | +// Permet le choix du mot de correction et lance le processus de remplacement | |
184 | 181 | void choice_word(correction liste, FILE* fp_txt, char end, int longueur, int* correct, bool testEnd) |
185 | 182 | { |
186 | - int choix; | |
187 | - printf("Voici les mots possibles pour corriger ce mot :\n"); | |
188 | - for(int i=0; i<liste->dernier+1; i++) | |
189 | - printf("%d. %s\n", i+1, liste->mots[i]); | |
190 | - printf("\n"); | |
191 | - choix = -1; | |
192 | - printf("Quel mot voulez-vous sélectionner ? (Entrez %d pour ne pas corriger le mot)\n", (liste->dernier)+2); | |
193 | - while(choix<1 || choix>liste->dernier+2) | |
194 | - { | |
195 | - scanf("%d", &choix); | |
196 | - } | |
197 | - if(choix==(liste->dernier)+2) | |
198 | - { | |
199 | - printf("\n"); | |
200 | - return; | |
201 | - } | |
202 | - (*correct)++; | |
203 | - char word[MAX]; | |
204 | - strcpy(word, liste->mots[choix-1]); | |
205 | - printf("Le mot %s a été sélectionné.\n\n", word); | |
206 | - if(testEnd) add_caract(word, end); | |
207 | - correct_word(word, fp_txt, longueur); | |
183 | + int choix; | |
184 | + printf("Voici les mots possibles pour corriger ce mot :\n"); | |
185 | + for(int i=0; i<liste->dernier+1; i++) // on propose tous les mots de la liste contigüe | |
186 | + printf("%d. %s\n", i+1, liste->mots[i]); | |
187 | + printf("\n"); | |
188 | + choix = -1; | |
189 | + printf("Quel mot voulez-vous sélectionner ? (Entrez %d pour ne pas corriger le mot)\n", (liste->dernier)+2); // exemple : 3 mots possibles. Si on entre 4, alors on ne veut pas corriger | |
190 | + while(choix<1 || choix>liste->dernier+2) // vérifie que la valeur entrée est correcte | |
191 | + { | |
192 | + scanf("%d", &choix); | |
193 | + } | |
194 | + if(choix==(liste->dernier)+2) // si on ne corrige pas | |
195 | + { | |
196 | + printf("\n"); | |
197 | + return; | |
198 | + } | |
199 | + (*correct)++; // on incrémente un compteur de corrections | |
200 | + char word[MAX]; // contiendra le mot choisi | |
201 | + strcpy(word, liste->mots[choix-1]); | |
202 | + printf("Le mot %s a été sélectionné.\n\n", word); | |
203 | + if(testEnd) add_caract(word, end); // s'il y a un caractère de fin, on l'ajoute | |
204 | + correct_word(word, fp_txt, longueur); // processus de remplacement | |
208 | 205 | } |
209 | 206 | |
207 | +// Remplace le mot comportant une erreur par le mot choisi dans choice_word | |
210 | 208 | void correct_word(char word[], FILE* fp_txt, int longueur) |
211 | 209 | { |
212 | - FILE* fp_tamp; | |
213 | - fp_tamp = fopen("tampon.txt", "w+"); | |
214 | - if(fp_tamp==NULL) | |
215 | - { | |
216 | - printf("Erreur lors de l'ouverture du fichier tampon.\n"); | |
217 | - return; | |
218 | - } | |
219 | - int position = ftell(fp_txt)-longueur; | |
220 | - rewind(fp_txt); | |
221 | - char tempo; | |
222 | - while(ftell(fp_tamp)<position) | |
210 | + FILE* fp_tamp; // création d'un fichier tampon | |
211 | + fp_tamp = fopen("tampon.txt", "w+"); // ouverture en mode lecture/écriture avec suppression du contenu au préalable | |
212 | + if(fp_tamp==NULL) | |
223 | 213 | { |
224 | - tempo = fgetc(fp_txt); | |
225 | - if(tempo==EOF) break; | |
226 | - //if(tempo=='\n'); | |
227 | - fputc(tempo, fp_tamp); | |
228 | - } | |
229 | - fprintf(fp_tamp, "%s", word); | |
230 | - long newPosition = ftell(fp_tamp); | |
231 | - fseek(fp_txt, ftell(fp_txt)+longueur, SEEK_SET); | |
232 | - while(1) | |
214 | + printf("Erreur lors de l'ouverture du fichier tampon.\n"); | |
215 | + return; | |
216 | + } | |
217 | + int position = ftell(fp_txt)-longueur; // on récupère la position dans le fichier à analyser du début du mot avec erreur | |
218 | + rewind(fp_txt); // on se place au début du fichier à scanner | |
219 | + char tempo; | |
220 | + while(ftell(fp_tamp)<position) // tant qu'on est pas arrivé au mot avec erreur | |
233 | 221 | { |
234 | - tempo = fgetc(fp_txt); | |
235 | - if(tempo==EOF) break; | |
236 | - //if(tempo=='\n'); | |
237 | - fputc(tempo, fp_tamp); | |
238 | - } | |
239 | - rewind(fp_txt); | |
240 | - rewind(fp_tamp); | |
241 | - char temp[MAX_READ]; | |
242 | - while(1) | |
243 | - { | |
244 | - if(fgets(temp, MAX_READ, fp_tamp)==NULL) | |
245 | - break; | |
246 | - fputs(temp, fp_txt); | |
247 | - } | |
248 | - fseek(fp_txt, newPosition, SEEK_SET); | |
249 | - fclose(fp_tamp); | |
250 | - remove("tampon.txt"); | |
222 | + tempo = fgetc(fp_txt); // copie d'un caractère à la fois | |
223 | + if(tempo==EOF) break; // jusque la fin du fichier | |
224 | + fputc(tempo, fp_tamp); // on ajoute le caractère dans le fichier tampon | |
225 | + } | |
226 | + fprintf(fp_tamp, "%s", word); // on ajout le mot corrigé dans le fichier tampon | |
227 | + long newPosition = ftell(fp_tamp); // on récupère la position de la fin du mot corrigé | |
228 | + fseek(fp_txt, ftell(fp_txt)+longueur, SEEK_SET); // on se place après le mot avec erreur dans le fichier à analyser | |
229 | + while(1) // on copie la fin du fichier à analyser dans le fichier tampon | |
230 | + { | |
231 | + tempo = fgetc(fp_txt); | |
232 | + if(tempo==EOF) break; | |
233 | + fputc(tempo, fp_tamp); | |
234 | + } | |
235 | + rewind(fp_txt); // on se remet au debut des 2 fichiers pour renvoyer le contenu du fichier tampon dans le fichier à analyser | |
236 | + rewind(fp_tamp); | |
237 | + char temp[MAX_READ]; | |
238 | + while(1) // on procède ligne par ligne car aucune modification sur un mot ne sera effectuée | |
239 | + { | |
240 | + if(fgets(temp, MAX_READ, fp_tamp)==NULL) | |
241 | + break; | |
242 | + fputs(temp, fp_txt); | |
243 | + } | |
244 | + fseek(fp_txt, newPosition, SEEK_SET); // on avait récupérer la position après le mot corrigé, on s'y place pour continuer l'analyse du fichier | |
245 | + fclose(fp_tamp); // fermeture du fichier tampon et suppression | |
246 | + remove("tampon.txt"); | |
251 | 247 | } |
252 | 248 | |
249 | +// Initialise la liste contigüe contenant les mots de correction | |
253 | 250 | void init_correction(correction* liste) |
254 | 251 | { |
255 | - if((*liste)!=NULL) | |
256 | - { | |
257 | - printf("Déjà initialisé.\n"); | |
258 | - return; | |
259 | - } | |
260 | - *liste = malloc(sizeof(struct liste)); | |
261 | - (*liste)->dernier = -1; | |
262 | - for(int i=0; i<NB_MOT_CORRECTION; i++) | |
263 | - { | |
264 | - strcpy((*liste)->mots[i], ""); | |
265 | - } | |
252 | + if((*liste)!=NULL) | |
253 | + { | |
254 | + printf("Déjà initialisé.\n"); | |
255 | + return; | |
256 | + } | |
257 | + *liste = malloc(sizeof(struct liste)); | |
258 | + (*liste)->dernier = -1; | |
259 | + for(int i=0; i<NB_MOT_CORRECTION; i++) | |
260 | + { | |
261 | + strcpy((*liste)->mots[i], ""); | |
262 | + } | |
266 | 263 | } |
267 | 264 | |
265 | +// Affichage | |
268 | 266 | void init_pgrm(void) |
269 | 267 | { |
270 | 268 | printf("\n------------------------------------------\n"); |
... | ... | @@ -273,6 +271,7 @@ void init_pgrm(void) |
273 | 271 | printf("------------------------------------------\n\n"); |
274 | 272 | } |
275 | 273 | |
274 | +// Renvoie true si 'word' ne comprend pas d'accent, false sinon | |
276 | 275 | bool no_accent(char word[]) |
277 | 276 | { |
278 | 277 | int index_max = max_index(word); |
... | ... | @@ -281,102 +280,104 @@ bool no_accent(char word[]) |
281 | 280 | return true; |
282 | 281 | } |
283 | 282 | |
283 | +// Lecture du fichier à analyser | |
284 | 284 | void read_txt(FILE* fp, Node* Tree, int* error, int* correct) |
285 | 285 | { |
286 | 286 | char word[MAX]; |
287 | 287 | while(1) |
288 | 288 | { |
289 | - if(fscanf(fp, "%s", word)!=1) | |
289 | + if(fscanf(fp, "%s", word)!=1) // tant qu'on a pas fini la lecture du fichier | |
290 | 290 | break; |
291 | - if(no_accent(word)) // !!! MOTS AVEC ACCENTS NON PRIS EN COMPTE | |
292 | - scan_word(*Tree, word, error, fp, correct); | |
291 | + if(no_accent(word)) // on ne prend pas en compte les mots accentués (voir compte-rendu pour explications) | |
292 | + scan_word(*Tree, word, error, fp, correct); // on scanne le mot | |
293 | 293 | } |
294 | 294 | if(feof(fp)) printf("Fin de la lecture du fichier à scanner.\n\n"); |
295 | 295 | if(ferror(fp)) printf("Erreur lors de la lecture du fichier à scanner.\n\n"); |
296 | 296 | } |
297 | 297 | |
298 | +// Lecture du dictionnaire | |
298 | 299 | void read_lib(FILE* fp, Node* Tree) |
299 | 300 | { |
300 | 301 | char word[MAX]; |
301 | 302 | while(1) |
302 | 303 | { |
303 | - if(fscanf(fp, "%s", word)!=1) | |
304 | + if(fscanf(fp, "%s", word)!=1) // tant qu'on a pas fini la lecture du fichier | |
304 | 305 | break; |
305 | - // printf("--%s--\n", word); | |
306 | - //fflush(stdout); | |
307 | - if(no_accent(word)) | |
308 | - add_in_tree(*Tree, word); | |
306 | + if(no_accent(word)) // on ne prend pas en compte les mots accentués (voir compte-rendu pour explications) | |
307 | + add_in_tree(*Tree, word); // on ajoute le mot dans l'arbre indexé | |
309 | 308 | } |
310 | 309 | if(feof(fp)) printf("Fin de la lecture de la bibliothèque.\n\n"); |
311 | 310 | if(ferror(fp)) printf("Erreur lors de la lecture de la bibliothèque.\n\n"); |
312 | 311 | } |
313 | 312 | |
313 | +// Affichage de l'arbre indexé (inutile pour le code, fonction d'aide) | |
314 | 314 | void print_tree(Node Tree, int index, char word[]) |
315 | 315 | { |
316 | - if(is_empty_tree(Tree)) | |
317 | - return; | |
318 | - add_caract(word, Tree->letter); | |
319 | - if(is_leaf(Tree)) | |
320 | - { | |
321 | - printf("%s\n", word); | |
322 | - supp_caract(word); | |
323 | - return; | |
324 | - } | |
325 | - if(Tree->endWord) | |
326 | - printf("%s\n", word); | |
327 | - while(index < NB_CARAC) | |
316 | + if(is_empty_tree(Tree)) // si l'arbre est vide, rien a imprimer | |
317 | + return; | |
318 | + add_caract(word, Tree->letter); // sinon, on stocke le caractère dans une chaine | |
319 | + if(is_leaf(Tree)) // si on atteint une feuille, on imprime et on supprime le dernier caractère car il n'est plus utile | |
320 | + { | |
321 | + printf("%s\n", word); | |
322 | + supp_caract(word); | |
323 | + return; | |
324 | + } | |
325 | + if(Tree->endWord) // si on est à la fin d'un mot, on l'imprime mais on enlève pas de lettre car il peut y avoir des mots plus grands de même racine | |
326 | + printf("%s\n", word); | |
327 | + while(index < NB_CARAC) // on parcourt tout le tableau de pointeur de chaque cellule | |
328 | + { | |
329 | + if(!is_empty_tree(Tree->next[index])) // si la case du tableau n'est pas vide | |
328 | 330 | { |
329 | - if(!is_empty_tree(Tree->next[index])) | |
330 | - { | |
331 | - print_tree(Tree->next[index], 0, word); | |
332 | - } | |
333 | - index++; | |
331 | + print_tree(Tree->next[index], 0, word); // on relance la fonction en partant de la case | |
334 | 332 | } |
335 | - supp_caract(word); | |
336 | - return; | |
333 | + index++; | |
334 | + } | |
335 | + supp_caract(word); // on supprime le dernier caractère stocké car il n'est plus utile | |
336 | + return; | |
337 | 337 | } |
338 | 338 | |
339 | -void make_tree_correct(Node Tree, int index, char word[], char start[], correction liste) | |
339 | +// Comme son nom l'indique, cette fonction sélectionne les mots possibles pour la correction du mot 'word' et les ajoute dans la liste contigüe | |
340 | +void make_tree_correct(Node Tree, int index, char word[], char start[], correction liste) // même principe que la fonction d'affichage de l'arbre indexé | |
340 | 341 | { |
341 | - if(is_empty_tree(Tree)) | |
342 | - return; | |
343 | - add_caract(word, Tree->letter); | |
344 | - if(is_leaf(Tree)) | |
345 | - { | |
346 | - //printf("%s%s\n", start, word); | |
347 | - add_in_liste(liste, start, word); | |
348 | - supp_caract(word); | |
349 | - return; | |
350 | - } | |
351 | - if(Tree->endWord) | |
352 | - { | |
353 | - //printf("%s%s\n", start, word); | |
354 | - add_in_liste(liste, start, word); | |
355 | - } | |
356 | - while(index < NB_CARAC) | |
342 | + if(is_empty_tree(Tree)) // si l'arbre est vide, il n'y a pas de correction possible | |
343 | + return; | |
344 | + add_caract(word, Tree->letter); // on ajoute le caractère à la chaine de stockage | |
345 | + if(is_leaf(Tree)) // si on arrive au bout d'une branche, on ajoute le mot dans la liste et on supprime le dernier caractère stocké | |
346 | + { | |
347 | + add_in_liste(liste, start, word); | |
348 | + supp_caract(word); | |
349 | + return; | |
350 | + } | |
351 | + if(Tree->endWord) // si on arrive à la fin d'un mot, on l'ajout dans la liste | |
352 | + { | |
353 | + add_in_liste(liste, start, word); | |
354 | + } | |
355 | + while(index < NB_CARAC) // on parcourt le tableau de chaque cellule | |
356 | + { | |
357 | + if(!is_empty_tree(Tree->next[index])) // si la case n'est pas vide | |
357 | 358 | { |
358 | - if(!is_empty_tree(Tree->next[index])) | |
359 | - { | |
360 | - make_tree_correct(Tree->next[index], 0, word, start, liste); | |
361 | - } | |
362 | - index++; | |
359 | + make_tree_correct(Tree->next[index], 0, word, start, liste); // on relance la fonction à partir de cette case | |
363 | 360 | } |
364 | - supp_caract(word); | |
365 | - return; | |
361 | + index++; | |
362 | + } | |
363 | + supp_caract(word); // on supprime le dernier caractère stocké, inutile maintenant | |
364 | + return; | |
366 | 365 | } |
367 | 366 | |
367 | +// Ajoute les mots de correction dans la liste contigüe | |
368 | 368 | void add_in_liste(correction liste, char start[], char word[]) |
369 | 369 | { |
370 | - char temp[MAX]; | |
371 | - strcpy(temp, start); | |
372 | - strcat(temp, word); | |
373 | - if(liste->dernier<NB_MOT_CORRECTION-1) | |
374 | - { | |
375 | - (liste->dernier)++; | |
376 | - strcpy(liste->mots[liste->dernier], temp); | |
377 | - } | |
370 | + char temp[MAX]; | |
371 | + strcpy(temp, start); // on concatène le debut du mot (avant l'erreur) avec la suite envoyée dans 'word' | |
372 | + strcat(temp, word); | |
373 | + if(liste->dernier<NB_MOT_CORRECTION-1) // pour ne pas dépasser le nombre de mots proposés | |
374 | + { | |
375 | + (liste->dernier)++; | |
376 | + strcpy(liste->mots[liste->dernier], temp); | |
377 | + } | |
378 | 378 | } |
379 | 379 | |
380 | +// Ajoute un caractère à une chaine de caractères | |
380 | 381 | void add_caract(char word[], char caract) |
381 | 382 | { |
382 | 383 | char str[2]; |
... | ... | @@ -385,11 +386,13 @@ void add_caract(char word[], char caract) |
385 | 386 | strcat(word, str); |
386 | 387 | } |
387 | 388 | |
389 | +// Supprime un caractère d'une chaine de caractères | |
388 | 390 | void supp_caract(char word[]) |
389 | 391 | { |
390 | 392 | word[strlen(word)-1]='\0'; |
391 | 393 | } |
392 | 394 | |
395 | +// Désalloue la mémoire utilisée par l'arbre indexé | |
393 | 396 | void free_tree(Node* Tree) |
394 | 397 | { |
395 | 398 | if(*Tree!=NULL) | ... | ... |
... | ... | @@ -9,10 +9,12 @@ |
9 | 9 | #include <stdlib.h> |
10 | 10 | #include <stdbool.h> |
11 | 11 | #include <string.h> |
12 | + | |
13 | +// Définition des constantes | |
12 | 14 | #define MAX 30 // taille maximale d'une chaîne lue dans un fichier |
13 | -#define NB_CARAC 27 // nombre de caractères différents pouvant être identifiés -> 89 avec accentués | |
15 | +#define NB_CARAC 27 // nombre de caractères différents pouvant être identifiés | |
14 | 16 | #define NB_MOT_CORRECTION 15 // nombre de mots pour la correction |
15 | -#define MAX_READ 1000 | |
17 | +#define MAX_READ 1000 // nombre de caractères maximums dans une ligne lue lors de la connexion | |
16 | 18 | |
17 | 19 | // Déclaration de la structure 'trie' ou 'arbre indexé', ainsi que des pointeurs associés |
18 | 20 | typedef struct node* Node; |
... | ... | @@ -23,7 +25,7 @@ typedef struct node { |
23 | 25 | bool endWord; |
24 | 26 | }node; |
25 | 27 | |
26 | -// Déclaration de la structure contenant les mots possible pour la correction | |
28 | +// Déclaration de la liste contigüe contenant les mots possible pour la correction | |
27 | 29 | typedef struct liste* correction; |
28 | 30 | |
29 | 31 | typedef struct liste { |
... | ... | @@ -76,7 +78,7 @@ void add_error(int*, char*, int, Node, FILE*, int*); |
76 | 78 | // Corrige les erreurs |
77 | 79 | void make_correction(char *, int, Node, FILE*, int*); |
78 | 80 | |
79 | -// Initialise le programme | |
81 | +// Initialise le programme (affichage) | |
80 | 82 | void init_pgrm(void); |
81 | 83 | |
82 | 84 | // Ajoute un caractère à une chaine de caractères |
... | ... | @@ -85,10 +87,10 @@ void add_caract(char*, char); |
85 | 87 | // Supprime le dernier caractère d'une chaine |
86 | 88 | void supp_caract(char*); |
87 | 89 | |
88 | -// Initialise le tableau contenant les mots de correction | |
90 | +// Initialise la liste contigüe contenant les mots de correction | |
89 | 91 | void init_correction(correction*); |
90 | 92 | |
91 | -// Imprime les mots possibles pour la correction | |
93 | +// Récupère les mots possibles pour la correction | |
92 | 94 | void make_tree_correct(Node, int, char*, char*, correction); |
93 | 95 | |
94 | 96 | // Ajoute un mot dans une liste contigûe | ... | ... |