babbbfbe
Corto Callerisa
ajout makefile
|
1
2
3
4
5
6
|
/**
* dictionnaire.c
*
* Implémente l'importation et la libération d'un dictionnaire en mémoire
* depuis un fichier texte.
*/
|
b2c30e82
Corto Callerisa
Push code des vac...
|
7
8
9
10
|
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
|
babbbfbe
Corto Callerisa
ajout makefile
|
11
|
/* ctype.h pour les fonctions isalpha, tolower, isdigit et isspace */
|
b2c30e82
Corto Callerisa
Push code des vac...
|
12
13
14
|
#include <ctype.h>
#include <string.h>
|
babbbfbe
Corto Callerisa
ajout makefile
|
15
|
#include "dictionnaire.h"
|
b2c30e82
Corto Callerisa
Push code des vac...
|
16
|
|
b2c30e82
Corto Callerisa
Push code des vac...
|
17
18
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
19
|
/* Variables globales */
|
b2c30e82
Corto Callerisa
Push code des vac...
|
20
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
21
22
|
// Declaration du Noeud racine
Noeud *racine;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
23
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
24
25
|
// Déclaration de reserve_noeud : permet d'allouer la taile du dictionnaire en une fois, simplifie la gestion
// mémoire.
|
b2c30e82
Corto Callerisa
Push code des vac...
|
26
27
|
Noeud *reserve_noeuds;
|
babbbfbe
Corto Callerisa
ajout makefile
|
28
29
30
31
32
33
34
|
// Déclaration du compteur de nombre de mots dans le dictionnaire.
// Est utilise par la fonction taille_dic().
unsigned int nbr_mots;
// Variable global permettant de construire une reserve de noeuds.
// Type "long" pour ne pas être limité.
long taille_fic;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
35
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
36
37
38
39
40
|
/**
* Teste si un mot appartient au dictionnaire.
* Retourne True si le mot est dans le dictionaire ou False sinon
*/
bool appartient(const char *mot) // Const pour que mot soit en lecture seule, il n'y a pas besoin de le modifier
|
b2c30e82
Corto Callerisa
Push code des vac...
|
41
|
{
|
babbbfbe
Corto Callerisa
ajout makefile
|
42
43
|
// Déclaration du pointeur parcourant le trie et initialisation a NULL
Noeud *nd_parcours_tmp = NULL;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
44
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
45
46
47
|
// Fais pointer nd_parcours_tmp sur la racine
// Pour chaque nouveau nd_parcours_tmp pointe sur la racine pour verifier le mot
nd_parcours_tmp = racine;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
48
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
49
|
// Variable pour iterer char par char dans un mot
|
b2c30e82
Corto Callerisa
Push code des vac...
|
50
51
|
int i = 0;
|
babbbfbe
Corto Callerisa
ajout makefile
|
52
|
// Vérifie que le le mot entré correspond à un parcours de l'arbre se terminant par mot_fini = True
|
b2c30e82
Corto Callerisa
Push code des vac...
|
53
|
while (mot[i] != '\0') {
|
babbbfbe
Corto Callerisa
ajout makefile
|
54
55
56
57
58
59
60
|
// On convertit le mot en minuscule pour se préoccuper uniquement de l'orthographe
char c;
if (isalpha(mot[i])) {
c = tolower(mot[i]);
} else {
c = mot[i];
}
|
b2c30e82
Corto Callerisa
Push code des vac...
|
61
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
62
63
64
65
66
67
68
69
70
|
// Gestion de l'apostrophe
if (c == '\'') {
// On regarde s'il existe un mot comprenant l'apostrophe, sinon le mot n'appartient pas au dico
if (nd_parcours_tmp->enfants[NB_CARAC - 1] == NULL) {
return false;
}
// Sinon on continue le parcours en allant au noeud suivant
nd_parcours_tmp = nd_parcours_tmp->enfants[NB_CARAC - 1];
}
|
b2c30e82
Corto Callerisa
Push code des vac...
|
71
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
72
73
74
75
76
|
// Gestion des lettres
else if (isalpha(c)) {
// Verifie que le parcours correspondant au lettres du mot existe jusqu'ici.
// Retourne False si ce n'est pas le cas.
if (nd_parcours_tmp->enfants[c - 'a'] == NULL) {
|
b2c30e82
Corto Callerisa
Push code des vac...
|
77
78
|
return false;
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
79
80
|
// Sinon on passe à la lettre suivante dans le dico
nd_parcours_tmp = nd_parcours_tmp->enfants[c - 'a'];
|
b2c30e82
Corto Callerisa
Push code des vac...
|
81
|
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
82
|
// On avance dans le mot à vérifier
|
b2c30e82
Corto Callerisa
Push code des vac...
|
83
84
|
i++;
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
85
86
87
|
// Retourne True si le mot existe dans le dictionnaire
return nd_parcours_tmp->mot_fini;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
88
89
|
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
90
91
92
93
94
|
/**
* Importe le dictionnaire en mémoire.
* Retourne True en cas de succes et False sinon.
*/
bool importer_dict(const char *nom_dic)
|
b2c30e82
Corto Callerisa
Push code des vac...
|
95
|
{
|
babbbfbe
Corto Callerisa
ajout makefile
|
96
97
98
99
|
// Ouvre le fichier du dictionnaire
// 'b' permet d'avoir un stream de byte et non l'interpretation des caractères d'indentation en fonction du système.
// Cela garantie que fseek determine correctement la taille du fichier.
FILE *dict = fopen(nom_dic, "rb");
|
b2c30e82
Corto Callerisa
Push code des vac...
|
100
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
101
|
// Erreur sur le fichier?
|
b2c30e82
Corto Callerisa
Push code des vac...
|
102
|
if (dict == false) {
|
babbbfbe
Corto Callerisa
ajout makefile
|
103
|
printf("Impossible d'ouvrir le fichier (dictionnaire.c)");
|
b2c30e82
Corto Callerisa
Push code des vac...
|
104
105
106
|
return false;
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
107
|
// Determination de la taille_dic du fichier (en bytes)
|
b2c30e82
Corto Callerisa
Push code des vac...
|
108
|
fseek(dict, 0, SEEK_END);
|
babbbfbe
Corto Callerisa
ajout makefile
|
109
|
taille_fic = ftell(dict);
|
b2c30e82
Corto Callerisa
Push code des vac...
|
110
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
111
|
// Remise du pointeur de fichier au debut
|
b2c30e82
Corto Callerisa
Push code des vac...
|
112
113
|
fseek(dict, 0, SEEK_SET);
|
babbbfbe
Corto Callerisa
ajout makefile
|
114
115
|
// Initalise reserve_noeuds avec suffisament de mémoire pour différents dictionnaires
reserve_noeuds = calloc(taille_fic, sizeof(Noeud));
|
b2c30e82
Corto Callerisa
Push code des vac...
|
116
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
117
118
|
// Premier Noeud du dictionnaire
Noeud *prochain_noeud_vide = reserve_noeuds;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
119
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
120
|
// On transfère le fichier depuis un stream dans un tableau
|
187c0e67
Corto Callerisa
ajout images pour...
|
121
|
char *buffer = malloc(taille_fic+1); // +1 pour le caractere de terminaison
|
babbbfbe
Corto Callerisa
ajout makefile
|
122
|
fread(buffer, 1, taille_fic, dict);
|
b2c30e82
Corto Callerisa
Push code des vac...
|
123
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
124
125
|
// Marque la fin du fichier
buffer[taille_fic] = '\0';
|
b2c30e82
Corto Callerisa
Push code des vac...
|
126
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
127
128
|
// Initialisation du Noeud racine du trie
racine = prochain_noeud_vide + 1;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
129
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
130
131
|
// Déclare et initialise le pointeur sur le Noeud courant
Noeud *nd_courant = NULL;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
132
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
133
134
|
// Nouveau string permettant de charger les mots dans le trie
char *mots_fichier = buffer;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
135
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
136
|
// Initialise le compteur pour la fonction taille()
|
b2c30e82
Corto Callerisa
Push code des vac...
|
137
138
|
nbr_mots = 0;
|
babbbfbe
Corto Callerisa
ajout makefile
|
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
// On boucle tant que le caractere n'est pas '\0' ou 'NULL'
while (*mots_fichier) {
// Départ du Noeud racine pour chaque mot
nd_courant = racine;
// Insère les mot dans l'espace mémoire pré-allouée.
// Si le char est un saut de ligne le mot est terminé fin d'un mot
for (; *mots_fichier != '\n' && *mots_fichier; mots_fichier++) {
// Gestion des mots avec apostrophe
if (*mots_fichier == '\'') {
// Si le mot avec apostrophe n'existe pas, on l'ajoute
if (nd_courant->enfants[NB_CARAC - 1] == NULL) {
nd_courant->enfants[NB_CARAC - 1] = prochain_noeud_vide++;
}
// Passage au noeud suivant
nd_courant = nd_courant->enfants[NB_CARAC - 1];
}
|
b2c30e82
Corto Callerisa
Push code des vac...
|
156
|
|
babbbfbe
Corto Callerisa
ajout makefile
|
157
|
// Gestion des lettres
|
b2c30e82
Corto Callerisa
Push code des vac...
|
158
|
else {
|
babbbfbe
Corto Callerisa
ajout makefile
|
159
160
161
|
// Si le mot n'existe pas, on l'ajoute en prenant le prochain noeud dans la réserve
if (nd_courant->enfants[*mots_fichier - 'a'] == NULL) {
nd_courant->enfants[*mots_fichier - 'a'] = prochain_noeud_vide++;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
162
|
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
163
164
|
// Passage au noeud suivant
nd_courant = nd_courant->enfants[*mots_fichier - 'a'];
|
b2c30e82
Corto Callerisa
Push code des vac...
|
165
166
167
|
}
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
168
169
170
|
// On est arrivé sur '\n' donc le mot est fini
nd_courant->mot_fini = true;
// Un mot de plus dans le dico
|
b2c30e82
Corto Callerisa
Push code des vac...
|
171
172
|
nbr_mots++;
|
babbbfbe
Corto Callerisa
ajout makefile
|
173
174
175
|
// On absorbe le saut de ligne
if (*mots_fichier == '\n') {
mots_fichier++;
|
b2c30e82
Corto Callerisa
Push code des vac...
|
176
177
178
|
}
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
179
|
// Fermeture proprement du fichier et libération de la mémoire
|
b2c30e82
Corto Callerisa
Push code des vac...
|
180
181
182
|
fclose(dict);
free(buffer);
|
babbbfbe
Corto Callerisa
ajout makefile
|
183
|
// Chargement avec succès
|
b2c30e82
Corto Callerisa
Push code des vac...
|
184
185
186
|
return true;
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
187
188
189
190
|
/**
* Retourne le nombre de mot dans un dictionnaire (0 si non chargé)
*/
unsigned int taille_dic()
|
b2c30e82
Corto Callerisa
Push code des vac...
|
191
|
{
|
babbbfbe
Corto Callerisa
ajout makefile
|
192
|
// Déjà calculée lors l'importation du dictionnaire
|
b2c30e82
Corto Callerisa
Push code des vac...
|
193
194
195
|
return nbr_mots;
}
|
babbbfbe
Corto Callerisa
ajout makefile
|
196
197
198
199
|
/**
* Libération du dictionnaire en mémoire.
* Retourne true en cas de succès et false sinon.
*/
|
b2c30e82
Corto Callerisa
Push code des vac...
|
200
201
|
bool decharger()
{
|
babbbfbe
Corto Callerisa
ajout makefile
|
202
203
|
// Avantage de l'appel unique à calloc :
// Un seul appel à free est nécéssaire !
|
b2c30e82
Corto Callerisa
Push code des vac...
|
204
|
free(reserve_noeuds);
|
babbbfbe
Corto Callerisa
ajout makefile
|
205
|
// Libération mémoire avec succès
|
b2c30e82
Corto Callerisa
Push code des vac...
|
206
207
|
return true;
}
|