Blame view

tree.c 10.3 KB
293e356c   grouille   Version quasi déf...
1
2
3
4
5
6
  // --------------------------------------------------------
  // Projet IMA3 2019 - Lecture d'une bibliothèque
  // Décompte du nombre de fautes d'orthographe dans un texte
  // Normand Quentin & Rouillé Guillaume
  // --------------------------------------------------------
  
7d87f7e2   grouille   Makefile + complè...
7
  #include "tree.h"
d74431cd   grouille   Ajout de tree.c
8
  
293e356c   grouille   Version quasi déf...
9
  // Fonction permettant de savoir si la structure est vide
54951130   grouille   Ajout du fichier ...
10
  bool is_empty_tree(Node Tree)
d74431cd   grouille   Ajout de tree.c
11
  {
54951130   grouille   Ajout du fichier ...
12
    return(Tree==NULL);
d74431cd   grouille   Ajout de tree.c
13
14
  }
  
293e356c   grouille   Version quasi déf...
15
  // Fonction permettant de savoir si le tableau 'next' est un tableau de pointeurs NULL
54951130   grouille   Ajout du fichier ...
16
  bool is_leaf(Node Tree)
d74431cd   grouille   Ajout de tree.c
17
  {
54951130   grouille   Ajout du fichier ...
18
19
20
21
    for(int i=0; i<NB_CARAC; i++)
      if(Tree->next[i] != NULL)
        return false;
    return true;
d74431cd   grouille   Ajout de tree.c
22
23
  }
  
293e356c   grouille   Version quasi déf...
24
  // Initialisation de la structure accueillant le dictionnaire
d74431cd   grouille   Ajout de tree.c
25
26
  void init_tree(Node* Tree)
  {
54951130   grouille   Ajout du fichier ...
27
    if(is_empty_tree(*Tree))
d74431cd   grouille   Ajout de tree.c
28
      {
54951130   grouille   Ajout du fichier ...
29
        *Tree = malloc(sizeof(node));
ffa95c23   grouille   Version finale sa...
30
        (*Tree)->letter = 7; //
d74431cd   grouille   Ajout de tree.c
31
        (* Tree)->endWord = false;
54951130   grouille   Ajout du fichier ...
32
        for(int i=0; i<NB_CARAC; i++)
293e356c   grouille   Version quasi déf...
33
          (*Tree)->next[i] = NULL; // initialisation du tableau 'next' à un tableau de pointeurs NULL
d74431cd   grouille   Ajout de tree.c
34
      }
3ff0cab7   grouille   Correction d'une ...
35
  } 
d74431cd   grouille   Ajout de tree.c
36
  
293e356c   grouille   Version quasi déf...
37
38
39
40
41
42
43
44
45
46
47
  // Détermine l'indice de rangement dans le tableau 'next' du caractère 'letter'
  int find_caract_indice(char letter) // Ne fonctionne pas pour les caractères accentués
  {
    //printf("__%d__\n", letter);
    if(letter>=97 && letter<=122) return letter-'a';
    if(letter>=65 && letter<=90) return letter-'A';
    if(letter == 39) return letter-13; // l'apostrophe est placée en 27ème position
    //if(letter>=192) {printf("%d", letter-166); return letter-166;} //-192+26
  }
  
  // Fonction d'ajout d'un mot 'word' dans la structure 'tree' de type 'arbre indexé'
54951130   grouille   Ajout du fichier ...
48
  void add_in_tree(Node Tree, char word[])
d74431cd   grouille   Ajout de tree.c
49
  {
293e356c   grouille   Version quasi déf...
50
51
    int j=0; // indice du caractère dans le mot 'word'
    int ind; // indice du caractère dans le tableau 'next'
54951130   grouille   Ajout du fichier ...
52
    Node Tree2 = Tree;
293e356c   grouille   Version quasi déf...
53
    while(word[j] != '\0') // on parcourt tout le mot 'word'
d74431cd   grouille   Ajout de tree.c
54
      {
293e356c   grouille   Version quasi déf...
55
56
        /*if(is_leaf(Tree2)) // a retirer
          printf("empty\t");*/
d74431cd   grouille   Ajout de tree.c
57
        char letter = word[j];
293e356c   grouille   Version quasi déf...
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
        ind = find_caract_indice(letter);
        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
        {
          Tree2 = Tree2->next[ind];
  	/* printf("%c %d\t", letter, ind);
  	   printf("okA %d\n", j);*/
        }
        else // sinon, on ajoute une nouvelle cellule de type 'struct node' et on y insère les informations concernant le caractères
        {
          Node new = NULL;
          new = malloc(sizeof(node));
          new->letter = letter; // le caractère
          for(int i=0; i<NB_CARAC; i++) // un tableau de pointeurs NULL
            {
              new->next[i]=NULL;
            }
ffa95c23   grouille   Version finale sa...
74
  	new->endWord = false;
293e356c   grouille   Version quasi déf...
75
          Tree2->next[ind] = new;  // on fait pointé le tableau du caractère précédent vers cette cellule (vers ce caractère)
ffa95c23   grouille   Version finale sa...
76
77
          if(!(Tree2->endWord)) // si le caractère n'est pas un caractère de fin, on le met à 'false' -> UTILITE ?
            Tree2->endWord = false;
293e356c   grouille   Version quasi déf...
78
79
80
81
          Tree2=Tree2->next[ind]; // on se place au niveau du caractère suivant dans l'arbre indexé
          /*printf("%c %d\t", letter, ind);
  	  printf("okB %d\n", j);*/
        }
d74431cd   grouille   Ajout de tree.c
82
        j++;
293e356c   grouille   Version quasi déf...
83
84
        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
          Tree2->endWord = true;
54951130   grouille   Ajout du fichier ...
85
      }
293e356c   grouille   Version quasi déf...
86
    //printf("ok\n");
54951130   grouille   Ajout du fichier ...
87
88
  }
  
293e356c   grouille   Version quasi déf...
89
  // Fonction qui détermine si le caractère est un caractère de fin de mot (espace, ',', ';', '.', etc..)
54951130   grouille   Ajout du fichier ...
90
91
  bool is_end_caract(char letter)
  {
12c9a42f   grouille   Modification du f...
92
    if(letter==0) return true;
293e356c   grouille   Version quasi déf...
93
    if((letter>=32 && letter<=38)||(letter>=40 && letter<=47)||(letter>=58 && letter<=64)||(letter>=123 && letter<=126)||(letter==128)) return true;
54951130   grouille   Ajout du fichier ...
94
95
96
    return false;
  }
  
293e356c   grouille   Version quasi déf...
97
  // Renvoi l'indice maximum du mot 'word'
54951130   grouille   Ajout du fichier ...
98
99
100
101
102
103
104
105
  char max_index(char word[])
  {
    int index = 0;
    while(!is_end_caract(word[index]))
      index++;
    return index;
  }
  
ffa95c23   grouille   Version finale sa...
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
54951130   grouille   Ajout du fichier ...
107
  {
293e356c   grouille   Version quasi déf...
108
    bool endWord = false;
12c9a42f   grouille   Modification du f...
109
    bool stop = false;
54951130   grouille   Ajout du fichier ...
110
    int ind = 0;
293e356c   grouille   Version quasi déf...
111
    int indice;
54951130   grouille   Ajout du fichier ...
112
113
114
115
    char letter;
    Node Tree2 = Tree;
    while(!is_end_caract(word[ind]))
    {
12c9a42f   grouille   Modification du f...
116
      stop = false;
54951130   grouille   Ajout du fichier ...
117
      letter = word[ind];
293e356c   grouille   Version quasi déf...
118
119
120
      indice = find_caract_indice(letter);
      
      if(Tree2 != NULL && Tree2->next[indice]!=NULL)
54951130   grouille   Ajout du fichier ...
121
122
      {
        ind++;
293e356c   grouille   Version quasi déf...
123
        Tree2 = Tree2->next[indice];
12c9a42f   grouille   Modification du f...
124
        endWord = Tree2->endWord;
54951130   grouille   Ajout du fichier ...
125
126
127
      }
      else
      {
ffa95c23   grouille   Version finale sa...
128
        add_error(error, word, ind, Tree2, fp_txt, correct);
293e356c   grouille   Version quasi déf...
129
        //printf("%d\n", ind);
54951130   grouille   Ajout du fichier ...
130
        ind = max_index(word);
293e356c   grouille   Version quasi déf...
131
        //printf("%d\n", ind);
12c9a42f   grouille   Modification du f...
132
        stop = true;
7d87f7e2   grouille   Makefile + complè...
133
        endWord = false;
d74431cd   grouille   Ajout de tree.c
134
      }
54951130   grouille   Ajout du fichier ...
135
    }
12c9a42f   grouille   Modification du f...
136
137
    if(!endWord && !stop)
      {
ffa95c23   grouille   Version finale sa...
138
        add_error(error, word, ind, Tree2, fp_txt, correct);
12c9a42f   grouille   Modification du f...
139
      }
54951130   grouille   Ajout du fichier ...
140
141
  }
  
ffa95c23   grouille   Version finale sa...
142
  void add_error(int* error, char word[], int index, Node Tree, FILE* fp_txt, int* correct)
0e62ceb1   grouille   Code propre
143
144
145
146
  {
    (*error)++;
    if(index==0)
      {
30391ee4   grouille   Correction légère
147
        printf("Le mot '%s' ne correspond à aucun mot du dictionnaire.\n\n", word);
0e62ceb1   grouille   Code propre
148
149
150
        return;
      }
    else if(index<strlen(word))
ffa95c23   grouille   Version finale sa...
151
        printf("Il y a une erreur dans le mot '%s', au caractère %c d'incide %d.\n", word, word[index], index);
0e62ceb1   grouille   Code propre
152
    else
ffa95c23   grouille   Version finale sa...
153
154
        printf("Il manque au moins une lettre au mot '%s'.\n", word);
    make_correction(word, index, Tree, fp_txt, correct);
0e62ceb1   grouille   Code propre
155
156
  }
  
ffa95c23   grouille   Version finale sa...
157
  void make_correction(char word[], int index, Node Tree, FILE* fp_txt, int* correct) // gestion des caractères de fin
0e62ceb1   grouille   Code propre
158
  {
ffa95c23   grouille   Version finale sa...
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
  	correction liste = NULL;
    	init_correction(&liste);
    	char end;
  	bool testEnd;
    	testEnd = detect_end_caract(&end, word);
    	int longueur = strlen(word);
    	Node Tree2 = Tree;
  	word[index-1]='\0';
    	printf("\n");
    	char words[MAX] = "";
    	make_tree_correct(Tree2, 0, words, word, liste);
    	choice_word(liste, fp_txt, end, longueur, correct, testEnd);
    	free(liste); // VALGRIND ???
  }
  
  bool detect_end_caract(char* end, char word[])
  {
  	if(is_end_caract(word[strlen(word)-1]))
  	  {
  		*end = word[strlen(word)-1];
  		return true;
  	  }
  	return false;
  }
  
  void choice_word(correction liste, FILE* fp_txt, char end, int longueur, int* correct, bool testEnd)
  {
  	int choix;
  	printf("Voici les mots possibles pour corriger ce mot :\n");
  	for(int i=0; i<liste->dernier+1; i++)
    		printf("%d. %s\n", i+1, liste->mots[i]);
    	printf("\n");
    	choix = -1;
    	printf("Quel mot voulez-vous sélectionner ? (Entrez %d pour ne pas corriger le mot)\n", (liste->dernier)+2);
    	while(choix<1 || choix>liste->dernier+2)
    	{
    		scanf("%d", &choix);
    	}
    	if(choix==(liste->dernier)+2) 
    	{
    		printf("\n");
    		return;
    	}
    	(*correct)++;
    	char word[MAX];
    	strcpy(word, liste->mots[choix-1]);
    	printf("Le mot %s a été sélectionné.\n\n", word);
  	if(testEnd) add_caract(word, end);
    	correct_word(word, fp_txt, longueur);
  }
  
  void correct_word(char word[], FILE* fp_txt, int longueur)
  {
  	FILE* fp_tamp;
  	fp_tamp = fopen("tampon.txt", "w+");
  	if(fp_tamp==NULL)
  	{
  		printf("Erreur lors de l'ouverture du fichier tampon.\n");
  		return;
  	}
  	int position = ftell(fp_txt)-longueur;
  	rewind(fp_txt);
  	char tempo;
  	while(ftell(fp_tamp)<position)
      {
      	tempo = fgetc(fp_txt);
      	if(tempo==EOF) break;
f2b17cb2   grouille   Correction d'une ...
226
227
      	//if(tempo=='\n');
  	fputc(tempo, fp_tamp);
ffa95c23   grouille   Version finale sa...
228
229
230
231
232
233
234
235
  	}
  	fprintf(fp_tamp, "%s", word);
  	long newPosition = ftell(fp_tamp);
  	fseek(fp_txt, ftell(fp_txt)+longueur, SEEK_SET);
  	while(1)
      {
        	tempo = fgetc(fp_txt);
      	if(tempo==EOF) break;
f2b17cb2   grouille   Correction d'une ...
236
237
      	//if(tempo=='\n');
         	fputc(tempo, fp_tamp);
ffa95c23   grouille   Version finale sa...
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
  	}
  	rewind(fp_txt);
  	rewind(fp_tamp);
  	char temp[MAX_READ];
  	while(1)
  	{
  		if(fgets(temp, MAX_READ, fp_tamp)==NULL)
  			break;
  		fputs(temp, fp_txt);
  	}
  	fseek(fp_txt, newPosition, SEEK_SET);
  	fclose(fp_tamp);
  	remove("tampon.txt");
  }
  
  void init_correction(correction* liste)
  {
  	if((*liste)!=NULL)
  	{
  		printf("Déjà initialisé.\n");
  		return;
  	}
  	*liste = malloc(sizeof(struct liste));
  	(*liste)->dernier = -1;
  	for(int i=0; i<NB_MOT_CORRECTION; i++)
  	{
  		strcpy((*liste)->mots[i], "");
  	}
0e62ceb1   grouille   Code propre
266
267
268
269
270
271
272
273
274
275
  }
  
  void init_pgrm(void)
  {
    printf("\n------------------------------------------\n");
    printf("Correcteur ortographique.\n");
    printf("Normand Quentin & Rouillé Guillaume.\n");
    printf("------------------------------------------\n\n");
  }
  
293e356c   grouille   Version quasi déf...
276
277
278
279
280
281
282
283
  bool no_accent(char word[])
  {
    int index_max = max_index(word);
    for(int i=0; i<index_max; i++)
      if(word[i]<0) return false;
    return true;
  }
  
ffa95c23   grouille   Version finale sa...
284
  void read_txt(FILE* fp, Node* Tree, int* error, int* correct)
54951130   grouille   Ajout du fichier ...
285
286
287
288
289
  {
    char word[MAX];
    while(1)
    {
      if(fscanf(fp, "%s", word)!=1)
7d87f7e2   grouille   Makefile + complè...
290
        break;
0e62ceb1   grouille   Code propre
291
      if(no_accent(word)) // !!! MOTS AVEC ACCENTS NON PRIS EN COMPTE
ffa95c23   grouille   Version finale sa...
292
        scan_word(*Tree, word, error, fp, correct);
54951130   grouille   Ajout du fichier ...
293
    }
0e62ceb1   grouille   Code propre
294
295
    if(feof(fp)) printf("Fin de la lecture du fichier à scanner.\n\n");
    if(ferror(fp)) printf("Erreur lors de la lecture du fichier à scanner.\n\n");
d74431cd   grouille   Ajout de tree.c
296
297
298
299
300
301
302
  }
  
  void read_lib(FILE* fp, Node* Tree)
  {
    char word[MAX];
    while(1)
      {
54951130   grouille   Ajout du fichier ...
303
        if(fscanf(fp, "%s", word)!=1)
7d87f7e2   grouille   Makefile + complè...
304
  	break;
293e356c   grouille   Version quasi déf...
305
        // printf("--%s--\n", word);
54951130   grouille   Ajout du fichier ...
306
        //fflush(stdout);
293e356c   grouille   Version quasi déf...
307
308
        if(no_accent(word))
  	add_in_tree(*Tree, word);
7d87f7e2   grouille   Makefile + complè...
309
      } 
0e62ceb1   grouille   Code propre
310
311
      if(feof(fp)) printf("Fin de la lecture de la bibliothèque.\n\n");
      if(ferror(fp)) printf("Erreur lors de la lecture de la  bibliothèque.\n\n");
d74431cd   grouille   Ajout de tree.c
312
313
  }
  
ffa95c23   grouille   Version finale sa...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
  void print_tree(Node Tree, int index, char word[])
  {
  	if(is_empty_tree(Tree))
  		return;
  	add_caract(word, Tree->letter);
  	if(is_leaf(Tree))
  	{
  		printf("%s\n", word);
  		supp_caract(word);
  		return;
  	}
  	if(Tree->endWord)
  		printf("%s\n", word);
  	while(index < NB_CARAC)
  	{
  		if(!is_empty_tree(Tree->next[index]))
  		{
  			print_tree(Tree->next[index], 0, word);
  		}
  		index++;
  	}
  	supp_caract(word);
  	return;
  }
0e62ceb1   grouille   Code propre
338
  
ffa95c23   grouille   Version finale sa...
339
  void make_tree_correct(Node Tree, int index, char word[], char start[], correction liste)
d74431cd   grouille   Ajout de tree.c
340
  {
ffa95c23   grouille   Version finale sa...
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
  	if(is_empty_tree(Tree))
  		return;
  	add_caract(word, Tree->letter);
  	if(is_leaf(Tree))
  	{
  		//printf("%s%s\n", start, word);
  		add_in_liste(liste, start, word);
  		supp_caract(word);
  		return;
  	}
  	if(Tree->endWord)
  	{
  		//printf("%s%s\n", start, word);
  		add_in_liste(liste, start, word);
  	}
  	while(index < NB_CARAC)
  	{
  		if(!is_empty_tree(Tree->next[index]))
  		{
  			make_tree_correct(Tree->next[index], 0, word, start, liste);
  		}
  		index++;
  	}
  	supp_caract(word);
  	return;
54951130   grouille   Ajout du fichier ...
366
367
  }
  
ffa95c23   grouille   Version finale sa...
368
  void add_in_liste(correction liste, char start[], char word[])
54951130   grouille   Ajout du fichier ...
369
  {
ffa95c23   grouille   Version finale sa...
370
371
372
373
374
375
376
377
  	char temp[MAX];
  	strcpy(temp, start);
  	strcat(temp, word);
  	if(liste->dernier<NB_MOT_CORRECTION-1)
  	{
  		(liste->dernier)++;
  		strcpy(liste->mots[liste->dernier], temp);
  	}
54951130   grouille   Ajout du fichier ...
378
379
  }
  
ffa95c23   grouille   Version finale sa...
380
  void add_caract(char word[], char caract)
54951130   grouille   Ajout du fichier ...
381
  {
ffa95c23   grouille   Version finale sa...
382
383
384
385
386
387
388
389
390
  	char str[2];
  	str[0] = caract;
  	str[1] = '\0';
  	strcat(word, str);
  }
  
  void supp_caract(char word[])
  {
  	word[strlen(word)-1]='\0';
d74431cd   grouille   Ajout de tree.c
391
392
  }
  
5db504f4   grouille   Ajout de la fonct...
393
  void free_tree(Node* Tree)
293e356c   grouille   Version quasi déf...
394
  {
5db504f4   grouille   Ajout de la fonct...
395
    if(*Tree!=NULL)
293e356c   grouille   Version quasi déf...
396
      {
5db504f4   grouille   Ajout de la fonct...
397
398
399
400
401
        for(int i=0; i<NB_CARAC; i++)
  	{
  	  free_tree(&(*Tree)->next[i]);
  	}
        free(*Tree);
293e356c   grouille   Version quasi déf...
402
      }
5db504f4   grouille   Ajout de la fonct...
403
  }
293e356c   grouille   Version quasi déf...