-- trova parola in un file di testo, crea indice analitico completo -- Ultima modifica : 27.06.2001 -- Autore: Paolo Canevascini & Denis Rossi -- Test su windows '98 gnatmake 3.13 with Ada.Text_Io,Ada.Characters.Handling , Ada.Integer_Text_Io, Ada. Strings.Fixed;-- ini librerie use Ada.Text_Io, Ada.Characters.Handling, Ada.Integer_Text_Io, Ada. Strings.Fixed; procedure Indice_Analitico is -- inizio procedura principale --variabili globali sono presenti in parecchie procedure e quindi ho preferito "globalizzarle" Stringa : String (1 .. 1000); Lung_Stringa : Natural; Scelta : Character; Nome_Parole_Indice : String (1 .. 200); Lung_Nome_Parole_Indice : Natural; File_Parole_Indice : File_Type; File_Di_Lettura : File_Type; Nome_File_Lettura : String (1 .. 200); Lung_File_Lettura : Natural; Altra_Ricerca : Character; Prima_Ricerca : Boolean := True; Nome_Testo : String (1 .. 200); Lung_Nome_Testo : Natural := 1; File_Parole_Indice_Def : File_Type; Parola_Indice : String (1 .. 30); Lung_Parola_Indice : Natural; --================================================== -- parte per trovare una parola in un file di testo --================================================== -- procedura che controlla la parola immessa dal utente con il testo del file procedure Controllo_Stringa ( Stringa : in String; Lung_String : in Natural; Parola : in String; Lung_Parola : in Natural; Risultato : in out Boolean ) is Pos : Natural; begin Pos := (Index(Stringa(1..Lung_String),Parola(1..Lung_Parola))); if Pos /= 0 then Risultato:= True; else Risultato:= False; end if; end Controllo_Stringa; -------------------------------------------- -- procedura che stampa i risultati della ricerca procedure Stampa_Risultato ( Parola : in String; Riga : in Natural; Lung_Parola : in Natural; Primo_Risultato : in Boolean ) is begin if Primo_Risultato = True then -- se è la prima volta che si trova la parola New_Line; Put ("** la parola "); Put (Parola(1..Lung_Parola)); Put (" si trova alla riga => "); Put(Riga,0); else-- se la parola è già stata trovata si mette solo virgola Put(", "); Put(Riga,0); end if; end Stampa_Risultato; -------------------------------------------- -- procedura per aprire un file procedure Apri_File ( Parola : in String; Lung_Parola : in Natural ) is Riga : Natural := 0; Risultato : Boolean := True; Controllo : Natural := 0; Primo_Risultato : Boolean := True; begin while not End_Of_File(File_Di_Lettura) loop Get_Line(File_Di_Lettura, Stringa, Lung_Stringa); Stringa := To_Lower(Stringa); -- i caratteri diventano tutti minuscoli Riga := Riga+1; Controllo_Stringa(Stringa, Lung_Stringa, Parola, Lung_Parola, Risultato);-- richiama la procedura di controllo if Risultato = True then Stampa_Risultato(Parola, Riga, Lung_Parola,Primo_Risultato); -- richiama la procedura che visualizza il risultato, se questo esiste Primo_Risultato:= False; Controllo := Controllo + 1; end if; end loop; if Controllo /= 0 then -- se non è più stata trovata la parola New_Line(2); Put("** la parola "); Put("'"); Put(Parola(1..Lung_Parola)); Put("'"); Put(" Non e` stata piu` trovata, fine ricerca."); New_Line; else -- se la parola non esiste all'interno del file New_Line; Put ("** '"); Put(Parola(1..Lung_Parola)); Put("' "); Put ("non esiste in nessuna riga del file."); New_Line; end if; end Apri_File; ----------------------------------------------- -- procedura per trovare una parola all`interno di un file procedure Trova_Parola is Parola : String (1 .. 50); Lung_Parola : Natural; Parola_Valida : Boolean := False; begin while Parola_Valida = False loop -- l'utente sceglie la parola Put("Inserire La Parola Da Cercare :"); Get_Line(Parola, Lung_Parola); Parola := To_Lower(Parola); Parola_Valida := True; for I in 1..Lung_Parola loop if Parola(I) = ' ' then -- se è presente uno spazio no viene accettato Put ("ho detto una sola parola, riprova ");New_line(2); Parola_Valida := False; end if; end loop; Prima_Ricerca:=False; if Parola_Valida= True then Apri_File(Parola,Lung_Parola); -- richiama la procedura per aprire un file end if; end loop; end Trova_Parola; ----------------------------------------------- --============================================= -- parte per creare l'indice analitico --============================================= -- procedura che elimina le parole doppie, righe vuote e mette in ordine alfabetico le parole da indicizzare procedure Ordina is File_Parole_Indice_Temp : File_Type; Parola_Indice_Temp : String (1 .. 50); Lung_Parola_Indice_Temp : Natural; Max_Arr : Natural := 1000; Max_Stringa_Arr : Natural := 30; type Parola is array (1 .. Max_Arr) of String (1 .. Max_Stringa_Arr); -- non si sa quante righe avra il file tem con le parole pulite Parola_Arr : Parola; Prima_Parola : Parola; Riga : Natural := 0; Posizione : Natural := 0; Tot_Parole : Natural := 0; begin --crazione del file che contiene l'indice analitico temporaneo Create( File => File_Parole_Indice_Temp, Mode => Out_File, Name => "indice_analitico_temp.txt", Form => ""); -- creazione del file che conterrà l'indice delle parole definitivo Create( File => File_Parole_Indice_Def, Mode => Out_File, Name => "indice_analitico_def.txt", Form => ""); --setaccia il file di parole scelte dall'utente e ne crea uno temporaneo senza spazi ne righe vuote while not End_Of_File(File_Parole_Indice) loop Get_Line(File_Parole_Indice, Parola_Indice,Lung_Parola_Indice); if Lung_Parola_Indice /= 0 then -- se la riga del file è vuota il prog la salta for I in 1..Lung_Parola_Indice loop if Parola_Indice(I) /= ' ' then -- se il carattere della riga non è ' ' il prog la copia nel file temp Put(File_Parole_Indice_Temp,Parola_Indice(I)); else if I > 1 then-- se invece il carattere è uno ' ' if Parola_Indice(I-1) /=' 'then -- e se il carattere precedente non è spazio New_Line(File_Parole_Indice_Temp); -- va a capo nel file temp vedi **(in fondo al file) end if; end if; end if; end loop; if Parola_Indice(Lung_Parola_Indice) /=' ' then -- se l'ultimo carattere non è ' ' va a capo **(in fondo al file) New_Line(File_Parole_Indice_Temp); end if; end if; end loop; Close(File_Parole_Indice_Temp); Open( File => File_Parole_Indice_Temp, Mode => In_File, Name => "indice_analitico_temp.txt", Form => ""); --metto i valori dell'array a ' ' for I in 1.. Max_Arr loop Parola_Arr(I):=(others =>' '); end loop; Prima_Parola(1) :=(others => ' '); --trasformo il file di testo temp (che però è stato setacciato) in un array di stringhe while not End_Of_File(File_Parole_Indice_Temp) loop Get_Line(File_Parole_Indice_Temp, Parola_Indice_Temp, Lung_Parola_Indice_Temp); Riga:= Riga+1; Parola_Arr(Riga)(1..Lung_Parola_Indice_Temp) := Parola_Indice_Temp(1..Lung_Parola_Indice_Temp); end loop; --conta quanti valori di array ci sono for I in 1.. Max_Arr loop if Parola_Arr(I)(1) = ' ' then Tot_Parole := I; exit; end if; end loop; -- elimino le parole doppie for I in 1.. tot_parole loop if Parola_Arr(I)(1)/=' ' then for J in 1 ..tot_parole-I loop if Parola_Arr(I+j)(1)/=' ' then if Parola_Arr(I) = Parola_Arr(J+I) then Parola_Arr(J+I) := (others => ' '); -- gli elementi che sono ripetitivi vengono messi a ' ' end if; end if; end loop; end if; end loop; -- metto in ordine alfabetico, faccio un controllo ogni volta ed alla --fine una sola parola e la prima in ordine alfabetico e questa -- viene copiata nel file indice_analitico_def.txt for A in 1.. Tot_Parole loop -- trovo la prima parola in ordine alfabetico Prima_Parola(1) :=(others =>' '); for I in 1..Tot_Parole loop for J in 1.. Tot_Parole loop if Parola_Arr(J)(1) /= ' ' then-- se la parola alla pos J è già stata azzerata la scarta Prima_Parola(1):= Parola_Arr(J);-- quando no trova una che è ancora valida questa diventa prima parola Posizione:= J;-- serve per cancellare l'array alla posizione giusta exit; end if; end loop; for K in Posizione..Tot_Parole-Posizione loop--passa il resto dell'array onfrontando tra di loro le parole if Parola_Arr(K+Posizione)(1) /= ' ' then -- se l'elemento dell'aray non è stato azzerato in precedenza... if Prima_Parola(1)>Parola_Arr(K+Posizione) then-- se prima parola è maggiore.. -- ... si fa il controllo Prima_Parola(1):=Parola_Arr(K+Posizione);--.... allora la parola alla pos k+posizione diventa prima Posizione:=K+Posizione; end if; -- a fine ricerca la parola che è alfabeticamente è prima parola end if; end loop; end loop; --copio la prima parola nel file file_indice_analitico_def.txt for I in 1.. Max_Stringa_Arr loop if Prima_Parola(1)(I) /= ' ' then Put(File_Parole_Indice_Def,Prima_Parola(1)(I)); end if; end loop; if Prima_Parola(1)(1) /= ' ' then New_Line(File_Parole_Indice_Def); end if; --la parola appena copiata viene azzerata cos`in nei prossimi cicli verra saltata perche è stata azzerata Parola_Arr(Posizione) := (others =>' '); end loop; Close(File_Parole_Indice_Def); Delete(File_Parole_Indice_Temp); end Ordina; ---------------------------------------------- -- procedura indice analitico file utente --crea un file indice analitico da un file di parole chiave e un file di testo normale procedure Indice_Utente is File_Testo : File_Type; File_Indice_Analitico : File_Type; Parola_Indice_Def : String (1 .. 50); Stringa_Testo : String (1 .. 1000); Riga_Testo : Natural := 0; Lung_Parola_Indice_Def : Natural; Lung_Stringa_Testo : Natural; Pos_Indice : Natural; Prima_Riga : Boolean := True; Lung_Analitico_Maggiorato : Natural; Nome_Analitico : String (1 .. 200) := (others => ' '); Stelle : String (1 .. 150) := (others => '*'); Lung_Stelle : Natural; Spazio_Titolo : String (1 .. 150) := (others => ' '); begin -- aprire il file in sola lettura che contiene il testo normale Lung_Analitico_Maggiorato:= 17+Lung_Nome_Testo; Nome_Analitico(1..Lung_Analitico_Maggiorato):="indice_analitico_"& Nome_Testo( 1..Lung_Nome_Testo); -- creazione del file che conterrà l'indice analitico definitivo con numero di riga con relativo nome Create( File => File_Indice_Analitico, Mode => Out_File, Name => Nome_Analitico (1 .. Lung_Analitico_Maggiorato), Form => ""); --procedura che setaccia il file che contiene le parole da indicizzare scelte dall'utente Ordina; -- viene richiamata la procedura ordina Open( File => File_Parole_Indice_Def, Mode => In_File, Name => "indice_analitico_def.txt", Form => ""); Open( File => File_Testo, Mode => In_File, Name => Nome_Testo (1 .. Lung_Nome_Testo), Form => ""); Lung_Stelle:=36+Lung_Nome_Testo; Nome_Testo:= To_Upper(Nome_Testo); New_Line(File_Indice_Analitico); New_Line(File_Indice_Analitico); Put(File_Indice_Analitico," ");Put(File_Indice_Analitico,Stelle(1..Lung_Stelle)); New_Line(File_Indice_Analitico); Put(File_Indice_Analitico," *");Put(File_Indice_Analitico,Spazio_Titolo(1..Lung_Stelle-2)); Put(File_Indice_Analitico,"*"); New_Line(File_Indice_Analitico); Put(File_Indice_Analitico," * INDICE ANALITICO DEL FILE << "); Put(File_Indice_Analitico,Nome_Testo(1..Lung_Nome_Testo)); Put(File_Indice_Analitico," >> *"); New_Line(File_Indice_Analitico); Put(File_Indice_Analitico," *");Put(File_Indice_Analitico,Spazio_Titolo(1..Lung_Stelle-2)); Put(File_Indice_Analitico,"*"); New_Line(File_Indice_Analitico); Put(File_Indice_Analitico," ");Put(File_Indice_Analitico,Stelle(1..Lung_Stelle)); New_Line(File_Indice_Analitico); New_Line(File_Indice_Analitico); New_Line(File_Indice_Analitico); New_Line(File_Indice_Analitico); -- esegue controllo tra parola indice e riga di testo nel file di testo while not End_Of_File(File_Parole_Indice_Def) loop Get_Line(File_Parole_Indice_Def, Parola_Indice_Def, Lung_Parola_Indice_Def); --memorizza la parola del file delle parole da indicizzarescelte dall'utente (setacciate e ordinate) Parola_Indice_Def := To_Lower(Parola_Indice_Def); -- tutti i caratteri minuscoli while not End_Of_File(File_Testo) loop --memorizza la riga di testo "normale" Get_Line(File_Testo, Stringa_Testo, Lung_Stringa_Testo); Stringa_Testo := To_Lower(Stringa_Testo); Riga_Testo:= Riga_Testo +1; Pos_Indice := (Index(Stringa_Testo(1.. Lung_Stringa_Testo), Parola_Indice_Def(1..Lung_Parola_Indice_Def))); -- verifica se la parola da indicizzare e presente nella riga di testo "normale" if Pos_Indice > 0 then -- se la parola è presente .. if Prima_Riga = False then -- se la parola è stata trovata più di una volta si separano i numeri di riga con una virgola Put(File_Indice_Analitico,", "); Put(File_Indice_Analitico,Riga_Testo,0); else -- se è la prima volta che si trova la parola si inseriscela parola seguita dal numero di riga in cui si trova Put (File_Indice_Analitico,Parola_Indice_Def(1.. Lung_Parola_Indice_Def)); Put(File_Indice_Analitico," => "); Put(File_Indice_Analitico,Riga_Testo,0); Prima_Riga := False; -- questo parametro segnala se la parola è stata trovata per la prima volta nel testo, end if; end if; end loop; if Prima_Riga = False then New_Line(File => File_Indice_Analitico); end if; -- riporta all'inizio il file di testo per ricominciare la ricerca con una nuova parola Reset(File_Testo); Prima_Riga:= True; Riga_Testo :=0; end loop; -- Chiusura dei file Close(File => File_Parole_Indice_Def); Close(File => File_Indice_Analitico); Close(File => File_Testo); Put( "Il file che contiene l'indice analitico e' stato salvato"); New_Line; Put( "nella cartella del programma e si chiama << "); Put(Nome_Analitico (1 .. Lung_Analitico_Maggiorato));Put(" >>"); New_Line(3); Put("scegliere 1 [trovare parola], 2 [creare indice analitico] o 3 [uscire] grazie"); New_Line(2); --canellare il file indice def(conteneva le parole da indicizzare uniche e alfabeticamente ordinate) Open( File => File_Parole_Indice_Def, Mode => In_File, Name => "indice_analitico_def.txt", Form => ""); Delete(File_Parole_Indice_Def); end Indice_Utente; ----------------------------------------------- begin Put ("benvenuti nel programma"); New_Line(2); Put(" 1 per trovare una parola nel file"); New_Line(2); Put( " 2 per creare indice analitico con un file che contiene le parole da indicizzare"); New_Line; Put( " 3 per uscire"); New_Line(2); loop Get_Immediate(Scelta); case Scelta is when '1' => -- -- -- aprire il file in sola lettura Put("in quale file desideri fare la ricerca? "); Get_Line(Nome_File_Lettura,Lung_File_Lettura); New_Line; Open(File_Di_Lettura,In_File,Nome_File_Lettura (1 .. Lung_File_Lettura), ""); loop if Prima_Ricerca = False then New_Line(2); Put("vuoi cercare un'altra parola[s/n]? "); Get_Immediate(Altra_Ricerca); New_Line(2); case Altra_Ricerca is when 's' => Reset(File_Di_Lettura); Trova_Parola; when 'n'=> new_line; put("scegliere 1 [trovare parola], 2 [creare indice analitico] o 3 [uscire] grazie"); New_Line(2); exit; when others => Put("inserire 's' o 'n'"); end case; else Trova_Parola; end if; end loop; -- Chiusura del file Close(File => File_Di_Lettura); when '2' =>-- procedura che permette di trovare una parola all'interno di un file -- procedura che permette di creare l'indice analitico di un testo -- sono necessari all'inizio perché altrimenti le procedure necessitano di questi dati --chiede nome del file che contine le parole da indicizzare Put( "dammi il nome del file che contiene le parole da indicizzare: "); Get_Line(Nome_Parole_Indice, Lung_Nome_Parole_Indice); New_Line(2); Put("dammi il nome del file che contiene il testo 'normale': "); Get_Line(Nome_Testo,Lung_Nome_Testo); New_Line(3); Put("ATTENZIONE! l'operazione potrebbe richiedere un po' di tempo ..."); New_Line(3); -- aprire il file in sola lettura che contiene le parole da indicizzare Open( File => File_Parole_Indice, Mode => Ada.Text_Io.In_File, Name => Nome_Parole_Indice (1 .. Lung_Nome_Parole_Indice), Form => ""); Indice_Utente; when '3' => exit; when others => Put("scegliere 1, 2 o 3 grazie"); New_Line(2); end case; end loop; end Indice_Analitico; --**spiegazioni sopra --se la striga e " , , ,c,a,s,a, , , ,v,i,o,l,a, , ," la procedura esegue i seguenti passi -- fiché ci sono spazi no copia il carattere nel file temp -- quando incontra caratteri li copia nel file di testo -- se incontra nuovamente uno spazio verifica il carattere precedente -- se quello precedente è una lettera significa che la parola è finita e si andrà a capo anche nel file temp -- proseguendo si analizza il carattere dopo lo spazio, il prog torna ad analizzare quello precedente -- si hanno allora due spazi consecutivi, il prog però stavolta non va nuovamente a capo. -- continuando ad analizzare la stringa incontra nuovamente un carattere e alloro lo copia nel file temp. -- quando anche la seconda parola è finita si fanno li stessi procedimenti di prima, unica eccezzione -- se l'ultimo carattere della stringa è uno spazio no si va a capo perché lo si è già fatto dopo la seconda parola. -- in questo modo il risultato che si ottiene è -- --c,a,s,a,"enter" --v,i,o,l,a,"enter"