Télécharger le script ! - mod phpBB
-- Extrait du projet Dictionnaire informatique.
--------------------------------------
----- ESTIENNE Sébastien -----
----- 02/06/2003 -----
--------------------------------------
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Characters.Handling; use Ada.Characters.Handling;
with Nt_Console; use Nt_Console;
package body Gestion_Dictionnaire is
-- Déclaration de la structure dictionnaire.
type Dictionnaire is record
Terme : pMot; -- un mot
Fichier : File_Type; -- pour stocker les infos du fichier dico
Nom : String(1..10); -- Nom du fichier dico
end record;
-- Ouvre un dictionnaire en lecture.
function Ouvrir_Lect_Dico(M : in pMot ; Fichier : in String) return pDictionnaire is
Dico : Pdictionnaire := new Dictionnaire; -- variable pDictionnaire
begin
Dico.Terme := M; -- stockage du mot dans le record Dico
Dico.Nom := Fichier; -- stockage du nom du fichier dans le record Dico
Open(Dico.Fichier, In_File, Fichier); -- On ouvre le fichier dico en lecture
return Dico; -- on retourne le record dico.
end Ouvrir_Lect_Dico;
-- Ferme un dictionnaire.
procedure Fermer_Dico(Dico : in pDictionnaire) is
begin
close(Dico.Fichier); -- Ferme le fichier dico.
end Fermer_Dico;
-- Retourne la définition d'un dico déjà ouvert.
function Lire_Def_Dico(Dico : in pDictionnaire) return pDefinition is
S : String(1..1024); -- Pour récupérer une ligne d'un fichier dico.
Taille : Natural; -- Nombre de caractère dans la chaine S.
I,J : Natural := 1; -- Sert de compteur pour des opérations.
Lg : natural := Lg_Mot(Dico.Terme); -- Longueur du mot
Trouve : Boolean := false; -- évident ;) mot trouvé
begin
-- on boucle tant que le mot n'a pas été trouvé (End_Of_File est plus une sécurité)
while(not(trouve) and not(End_Of_File(Dico.Fichier))) loop
Get_Line(Dico.Fichier, S, Taille); -- On récupère la ligne courante.
-- la valeur de I va permettre de connaître la position du dernier caractère du mot de cette ligne
I := 1;
while(S(I)/=' ') loop
I := I+1;
end loop;
if(I-1 = Lg) then -- dans ce cas il est possible que l'on ait trouvé le mot
Trouve := True; -- si trouve reste a true, on a trouvé notre mot
J := 1; -- un mot est toujours au début de S
while(trouve and J<=Lg) loop -- comparaison caractère par caractère de Dico.Terme et S(1..Lg)
if(To_Basic(To_Lower(S(J))) /= To_Basic(To_Lower(Niemechar_Mot(Dico.Terme,J)))) then Trouve := False; end if;
J := J + 1;
end loop;
end if;
-- Dans ce cas, on peut lire la définition
if(trouve) then
while(S(I) = ' ' or S(I) = ':') loop -- on élimine les caractères superflus
I := I+1;
end loop;
end if;
end loop;
return Creer_Definition(S(I..Taille)); -- on crée notre définition
end Lire_Def_Dico;
-- Crée/Ecrit/Ajoute une entité mot+définition dans un dictionnaire.
procedure Creer_Dico(M : in Pmot ; Ind : out Index ; Nom : in String) is
S : String(1..1024); -- pour le mot et sa définition
Lg_S : Natural; -- longueur significative de S
S_Def : String(1..768); -- Chaîne de caractère pour la définition
Lg_SDef : Natural; -- longueur significative de S_Def
Cpt : Natural; -- compteur pour différent calculs
Nbdef : Natural := 0; -- Nombre de définitions de l'index
Lastfile : String(1..10); -- Nom du dernier fichier dictionnaire
NbDico : Natural := 0; -- Nom du fichier dico en natural
Nbdef_Lastfile : Natural := 0; -- Nombre de définition du dernier fichier dictionnaire
N : constant Natural := Character'Pos(''); -- code ascci de '00'
Fichier : File_Type; -- pour stocker des infos relatives à un fichier
S_Fic : String(1..50); -- Chaine de caractère pour le fichier dico.ini
Nb_Sfic : Natural; -- longueur significative de S_Fic
Diz : Natural := 1; -- les "dizaines" pour conversion string->natural
Ht : Boolean := true; -- booleen pour l'équilibre de l'arbre.
-- Permet de lire une suite de caractère d'une longueur définie
procedure Lit_chaine(S : out String) is
C : Character; J : Integer := S'First;
begin
for I in S'range loop S(I):=' '; end loop; -- initialisation de la chaîne de caractères.
while (not(End_Of_Line)) loop Get(C); S(J) := C; J := J+1; end loop; -- récupère les caractères et les copie dans "S".
end Lit_chaine;
-- Permet de calculer le nb d'espaces superflus à la fin d'une chaîne de caractères.
function Traite_Espaces(S : in String) return Natural is
Fin : Natural;
begin
Fin:=S'Last-S'First+1; -- calcul de la lg de la chaîne de caractères.
while S(Fin)=' ' loop Fin := Fin-1; end loop; -- On repère les espaces en trop en partant de la fin.
return Fin; -- on retourne la valeur.
end Traite_Espaces;
begin
-- Récupère nombre de définition totales (NbDef)
Open(Fichier, In_File, Nom); -- Ouvre le fichier index
Get_Line(Fichier, S_Fic, Nb_Sfic); -- récupère la ligne ou se trouve le nombre de Def de l'index
for I in reverse 1..Nb_Sfic loop -- convertit la chaîne de caractère en natural
NbDef := NbDef + Diz*(Character'Pos(S_Fic(I))-N);
Diz := Diz * 10;
end loop;
Close(Fichier); -- ferme le fichier index
-- Récupère le nom du dernier fichier dico (LastFile)
Open(Fichier, In_File, "dico.ini"); -- Ouvre dico.ini
Get_Line(Fichier, S_Fic, Nb_Sfic); -- récupère la ligne où se trouve le nom du dernier fichier dico
for I in 1..10 loop -- on extrait et stocke les données dans variable LastFile (string)
Lastfile(I) := S_Fic(I+Nb_Sfic-10);
end loop;
-- Récupère nombre de définition du dernier fichier dico (NbDef_LastFile)
Get_Line(Fichier, S_Fic, Nb_Sfic); -- récupère la ligne où se trouve le nombre de def du dernier fichier dico
Cpt := Nb_Sfic; Diz := 1; -- initialisation car on part des unités (fin chaine) & => diz = 1.
while(S_Fic(Cpt) /= ' ') loop -- convertit la chaîne de caractère en natural
NbDef_LastFile := NbDef_LastFile + Diz*(Character'Pos(S_Fic(Cpt))-N);
Diz := Diz*10;
Cpt := Cpt - 1;
end loop;
Close(Fichier); -- ferme le fichier dico.ini
-- Ecrit dans une chaine de caractère le mot et sa définition
for I in 1..Lg_Mot(M) loop -- on écrit le mot caractère par caractère dans S.
S(I) := Niemechar_Mot(M,I);
end loop;
S(Lg_Mot(M)+1..Lg_Mot(M)+3) := " : "; -- on écrit " : " dans S.
loop
begin
Set_Foreground(Yellow); -- couleur du texte en jaune
Put("Donnez la definition du mot :"); -- on demande la définition à l'utilisateur
New_Line; Skip_Line; Set_Foreground(Light_Green); -- on revient à la ligne, on enlève les caractère en cache, on change la couleur du texte en vert clair
Lit_Chaine(S_Def); -- on récupère la chaine de caractère.
Lg_Sdef := Traite_Espaces(S_Def); -- on calcule la longueur significative de la définition.
exit;
exception
when Constraint_Error => Set_Foreground(Light_Red); Put_Line(" ! Definition trop longue."); -- si la définition dépasse 768 caractèes!
end;
end loop;
for I in 1..Lg_SDef loop -- on copie dans S la définition;
S(I+Lg_Mot(M)+3) := S_Def(I);
end loop;
Lg_S := Lg_SDef+Lg_Mot(M)+3; -- on recalcule la longueur significative de S.
-- On écrit le mot+def dans un fichier dico.
if(Nbdef_Lastfile <= 9) then -- *** cas où on peut ajouter une def ds le fichier ***
Open(Fichier, Append_File, Lastfile); -- on ouvre le fichier dico courant en mode ajout.
Put_Line(Fichier, S(1..Lg_S)); -- on écrit le mot et la définition à la fin du fichier.
Close(Fichier); -- on ferme le fichier dico.
Nbdef_Lastfile := Nbdef_Lastfile + 1; -- màj du nb de def contenues ds le dernier fichier dico.
else -- *** cas où il faut créer un nouveau fichier dico ***
-- calcul du nom du nouveau et dernier fichier dico
Diz := 1; -- diz=1 car on commence par les unités
for I in reverse 1..6 loop -- on convertit la première partie du nom du fichier dico en natural (sur 6 chiffres)
Nbdico := Nbdico + Diz*(Character'Pos(Lastfile(I))-N);
Diz := Diz * 10;
end loop;
Nbdico := Nbdico + 1; -- "on calcule le nom du nouveau fichier dico".
cpt := 6; -- la première partie du nom est sur 6 chiffres.
while(NbDico>0) loop -- on convertit le nombre (NbDico) en chaine de caractère pour le nv nom
Lastfile(Cpt) := Character'Val(N + Nbdico mod 10);
NbDico := NbDico / 10;
cpt := cpt - 1;
end loop;
Create(Fichier, Out_File, Lastfile); -- maintenant que l'on a le nom, on crée le fichier (mode écriture).
Put(Fichier, S(1..Lg_S)); -- on écrit le mot et la définition à la fin du fichier.
Close(Fichier); -- on ferme le fichier.
Nbdef_Lastfile := 1; -- màj du nb de def contenues ds le dernier fichier dico.
end if;
-- Màj du fichier dico.ini
Create(Fichier, Out_File, "dico.ini"); -- on écrase le fichier dico.ini
Put(Fichier, "LastFile : ");
Put_Line(Fichier, LastFile); -- on inscrit le nom du dernier ficheir dico
Put(Fichier, "NbDef_LastFile :");
Put_Line(Fichier, Natural'Image(Nbdef_Lastfile)); -- on inscrit le nb de def contenues dans le dernier fichier dico
Close(Fichier); -- on ferme le fichier dico.ini
-- ajout du mot à l'index et son fichier
NbDef := NbDef + 1; -- on augmente de 1 le nb de def de l'index
Ajout_Index(Ind, Ht, M, LastFile); -- on met à jour l'index (arbre binaire) => AVL
Create(Fichier, Out_File, Nom); -- on écrase le fichier index car ne sait pas ouvrir fichier en inout
Put_Line(Fichier, Natural'Image(Nbdef)(2..Natural'Image(NbDef)'length)); -- on écrit le nombre de définition au tout début du fichier
Parcours_Index(Ind, Fichier); -- cette fct écrit tout les mots et leur fichier dico correspondant
Close(Fichier); -- on ferme le fichier index
end Creer_Dico;
end Gestion_Dictionnaire;