Written by xinyimanposted in Lazarus 1.0 Ottobre 20, 2011, 12:24:00 pm21627 ViewsRating: 0 (0 Rates)Print
Spesso può capitare che all'avvio di un software si necessiti di caricarsi dei dati, per esempio i dati di connessione ad un DB. Per fare questo ci vengono in aiuto i comodissimi file INI.
Un file ini è un semplice file di testo che finisce con estensione ini, ed è strutturato per sezioni, facciamo l'esempio di aver la necessità di caricare i dati per la connessione al database e i dati di altre configurazioni (lingua, versione, email,...).
Il file ini incriminato dovrebbe essere così strutturato
[ConnDB]
Host=localhost
Nick=pippo
Pwd=pluto
DBFile=c:\appoggio.s3db
[Altro]
Lingua=italiano
Ver=1.0
Questo file va salvato in C:\ con il nome Config.ini per poter essere coerente con l'esempio successivo.
Il programma che andrebbe a leggere questi dati dovrebbe essere così strutturato:
Program Project1;
{$mode objfpc}{$H+}
Uses
Classes,SysUtils
,INIFiles {libreria per usare i file ini}
;
Var
INI:TINIFile;
Nick,Pwd,Host,DBFile, Lingua,Versione:String;
begin
INI := TINIFile.Create('C:\Config.ini');
Nick := INI.ReadString('ConnDB','Nick','');
Pwd := INI.ReadString('ConnDB','Pwd','');
Host := INI.ReadString('ConnDB','Host','');
DBFile := INI.ReadString('ConnDB','DBFile','');
Lingua := INI.ReadString('Altro','Lingua','');
Versione:= INI.ReadString('Altro','Ver','');
Ini.Free; // After we used ini file, we must call the Free method of object
{Faccio qualcosa con questi dati}
...
end.
Come vedete è parecchio semplice usare i file ini nei propri progetti. Ovviamente non è il massimo lasciare in chiaro le password nei file ini, ma l'esempio sopra voleva essere semplice. In un prossimo how to spieghero come usare le funzioni crittografiche di Lazarus/Free Pascal, e con quelle nozioni capirete come ovviare al problema delle password in chiaro nei file INI.
Precedentemente si è parlato dei vettori come una serie
di celle una dietro l'altra in linea orizzontale, si possono
immaginare le matrici come un rettangolo o un quadrato di celle. Per
esempio si può immaginare questo come un vettore di 8 celle:
CELLA0
CELLA1
CELLA2
CELLA3
CELLA4
CELLA5
CELLA6
CELLA7
Mentre si può immaginare quanto segue come una matrice
di 5x4 celle:
CELLA0,0
CELLA0,1
CELLA0,2
CELLA0,3
CELLA0,4
CELLA1,0
CELLA1,1
CELLA1,2
CELLA1,3
CELLA1,4
CELLA2,0
CELLA2,1
CELLA2,2
CELLA2,3
CELLA2,4
CELLA3,0
CELLA3,1
CELLA3,2
CELLA3,3
CELLA4,4
Le matrici infatti si possono chiamare anche array
multidimensionali. Gli scopi di una matrice sono molteplici,
immaginiamo ad esempio il gioco degli scacchi, la scacchiera può
essere rappresentata semplicemente con una matrice. La dichiarazione
di una matrice si definisce così: nomevariabile:
array[Altezza,Larghezza] of tipodivariabile; vediamo un
esempio, se volessimo dichiarare la matrice sopra riportata di 5x4
celle dovremmo procedere così: Matrice1:
array[0..4,0..3] of integer;. Anche l'uso non è dissimile
dai vettori monodimensionali, prendiamo come esempio la matrice di
prima e vediamo di riempirla con dei numeri consecutivi.
program
project1;
{$mode
objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils, CustApp
{
you can add units after this };
type
{
TMyApplication }
TMyApplication = class(TCustomApplication)
protected
procedure DoRun; override;
public
end;
{
TMyApplication }
procedure
TMyApplication.DoRun;
var
Matrice: array[0..4,0..3] of integer;
i,j,
contatore: integer;
begin
{
add your program here }
contatore:=0;
for
i:=0 to 4 do
begin
for j:=0 to 3 do
begin
Matrice[i,j]:=contatore;
contatore:=contatore+1;
end;
end;
for
i:=0 to 4 do
begin
write('|');
for j:=0 to 3 do
begin
if (Matrice[i,j]<=9) then
begin
write('0',Matrice[i,j],'|');
end
else
write(Matrice[i,j],'|');
end;
writeln();
end;
//
stop program loop
Terminate;
end;
var
Application: TMyApplication;
{$IFDEF
WINDOWS}{$R project1.rc}{$ENDIF}
begin
Application:=TMyApplication.Create(nil);
Application.Title:='My Application';
Application.Run;
Application.Free;
end.
Se provate a compilare e ad eseguire il codice appena
scritto vedrete il risultato del vostro lavoro.
Esattamente come per i vettori anche le matrici possono
essere statiche o dinamiche, quelle appena dichiarate sono statiche,
ora vediamo le dinamiche. Sostanzialmente cambia in fase di
dichiarazione della variabile, ipotizziamo di voler rifare l'esempio
di poco fa sulla matrice statica con una dinamica la dichiarazione
della variabile di nome matrice verrebbe così modificata: Matrice:
array of array of integer;. Dopodichè dobbiamo definire
quanto è grossa la matrice, ma lo facciamo nella fase esecutiva in
questa maniera SetLength(Matrice,5,4).
Insomma se dovessimo riscrivere il programma con una matrice dinamica
il codice sarebbe il seguente:
program
project1;
{$mode
objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes, SysUtils, CustApp
{
you can add units after this };
type
{
TMyApplication }
TMyApplication = class(TCustomApplication)
protected
procedure DoRun; override;
public
end;
{
TMyApplication }
procedure
TMyApplication.DoRun;
var
Matrice: array of array of integer;
i,j,
contatore: integer;
begin
{
add your program here }
SetLength(Matrice,5,4);
contatore:=0;
for
i:=0 to 4 do
begin
for j:=0 to 3 do
begin
Matrice[i,j]:=contatore;
contatore:=contatore+1;
end;
end;
for
i:=0 to 4 do
begin
write('|');
for j:=0 to 3 do
begin
if (Matrice[i,j]<=9) then
begin
write('0',Matrice[i,j],'|');
end
else
write(Matrice[i,j],'|');
end;
writeln();
end;
//
stop program loop
Terminate;
end;
var
Application: TMyApplication;
{$IFDEF
WINDOWS}{$R project1.rc}{$ENDIF}
begin
Application:=TMyApplication.Create(nil);
Application.Title:='My Application';
Application.Run;
Application.Free;
end.
Provate a compilare e ad eseguire il programma e capirete cosa abbiamo/avete fatto.
Fino ad adesso abbiamo visto dei tipi di dati semplici,
delle variabili mono-valore, infatti in base alle conoscenze fino a
qui acquisite se dovessimo immettere dieci valori numerici e
mantenerli in memoria avremmo dovuto dichiarare 10 variabili diverse,
ad esempio variabile1, variabile2, fino a variabile10.
Con i vettori o array questo problema è facilmente
superabile perché con una sola dichiarazione si possono memorizzare
più valori. Per capire meglio come ciò è possibile si può
immaginare la memoria come un insieme di tante celle, se dichiaro una
variabile come fino ad ora visto occupo una di queste celle, invece
se dichiari un vettore è come occupare da una a N celle consecutive.
Quindi ricapitolando se volessimo realizzare l'esempio di prima con
questa soluzione dovremmo dichiarare la variabile così variabile1:
Array[0..9] of integer. In questo modo abbiamo
metaforicamente ma neanche poi tanto dichiarato che 10 celle della
memoria si chiamano variabile1, e per poter leggere o cambiare il
valore di ogni singola cella usiamo un contatore da 0 a 9 ovvero
l'identificativo di ogni singola cella del valore.
Vediamo un esempio per capire meglio come utilizzare gli
array. Ovviamente apriamo una nuova "Console Application" e la
compiliamo in modo che sia tale e quale a questo codice qui sotto.
Bene quello che è stato aggiunto al codice iniziale
sono la dichiarazione di queste due variabili
variabile1: array[0..9] of integer;
i:
integer;
e queste righe di codice.
for
i:=0 to 9 do
begin
variabile1[i]:=i+10;
end;
for
i:=0 to 9 do
begin
writeln('Il valore della cella ', i,'
e'':',variabile1[i]);
end;
Come possiamo vedere la parte importante è
nell'esecuzione dei due cicli for. Il primo immette nelle celle del
vettore un valore che varia da 10 a 19 e nel secondo ciclo scrivo a
video questi 10 valori contenuti in variabile1. Un'altra cosa
importante da notare è che in fase di dichiarazione bisogna anche
dire al programma di che tipo è il vettore, nel nostro caso è
integer.
Bene quello che fino ad ora si è detto sui vettori si
può classificare come "vettori statici", ora vedremo anche
quelli dinamici. Si differenziano uno dall'altro dalla mancata
dichiarazione della lunghezza del vettore. Un vettore statico infatti
si dichiara così: nomevariabile: array[lunghezza] of
tipodivariabile; mentre un vettore dinamico si dichiara
così: nomevariabile: array of tipodivariabile;.
Vediamo ora un esempio per capire come si usano. Dopo aver dichiarato
la seguente variabile così: Variabile1: array of
integer; bisogna inserire il codice sottostante nella fase
esecutiva del programma.
SetLength(Variabile1,6);
for
i:=0 to 5 do
begin
Variabile1[i]:=i;
end;
for
i:=0 to 5 do
begin
writeln('Valore 1: ',Variabile1[i]);
end;
La prima cosa che bisogna notare è la procedura
SetLength che serve a stabilire quanto è lungo il vettore, perché
nel caso di un vettore statico una volta stabilita la lunghezza del
vettore quello rimane per tutta l'esecuzione del programma, mentre
per i vettori dinamici la lunghezza del vettore può variare
resettandone la lunghezza. Per il resto è tutto uguale ai vettori
statici.
Può capitare che prima o poi ci si imbatta nella
necessità di dover generare dei numeri casuali (in realtà pseudo-casuali), ovvero numeri scelti
a caso dal computer, anche in questo caso ci viene in aiuto il
linguaggio. Per ottenere un numero casuale contenuto tra 0 e N ci
viene in aiuto la funzione RANDOM, che viene parametrizzata con il
valore massimo che può raggiungere, quindi ipotizziamo di voler
avere un numero casuale tra 0 e 5 allora dobbiamo parametrizzare la
funzione così: random(5) e assegnare il
valore ad una variabile. Per poter generare i numeri casuali prima
bisogna inizializzare il generatore di numeri casuali. Per fare ciò
utilizziamo la procedura RANDOMIZE. Vediamo ora un esempio pratico
per capire meglio come si ottengono i numeri casuali. Ipotizzando di
voler simulare il lancio di un dado (cioè i numeri casuali possono
variare da 1 a 6), e ipotizziamo di aver dichiarato una variabile di
tipo integer e di nome Dado, questo dovrebbe essere il codice da
scrivere:
Randomize;
Dado:=Random(5)+1;
writeln('Il dado restituisce il valore: ', Dado);
Analizzando il codice vediamo che per prima cosa
inizializziamo il generatore di numeri casuali, per secondo generiamo
un numero casuale da 0 a 5 e poi lo incrementiamo di uno, per finire
stampiamo il risultato a monitor. Ovviamente se dovevamo generare un
numero che partisse da uno e arrivasse a 6 dovevamo per forza
eliminare l'opzione 0 dai possibili risultati e parametrizzando
random con 6 ciò non sarebbe stato possibile.
Esattamente come per le variabili di tipo numerico anche
per le variabili di tipo carattere sono presenti delle funzioni
native del linguaggio che permettono di lavorare su di esse. Le più
comuni ed utilizzate sono le seguenti.
ORD(x): immaginiamo di avere una variabile carattere di
nome x e ipotizziamo di voler sapere qual'è il suo corrispettivo
numerico, utilizzando la funzione ORD sarà possibile ottenere il
risultato che ci siamo proposti (esempio A equivale a 65).
CHR(x): la funzione CHR è l'esatto opposto della
funzione ORD, ovvero da un valore numerico possiamo ricavare il suo
valore carattere (esempio 65 equivale ad A).
SUCC(x): con la funzione SUCC possiamo sapere quale
carattere viene dopo a quello contenuto nella variabile x (esempio se
la variabile x contiene A il risultato sarà B).
PRED(x): con la funzione PRED possiamo sapere quale
carattere viene prima di quello contenuto nella variabile x (esempio
se la variabile x contiene D il risultato sarà C).
UPPERCASE(x): la funzione UPPERCASE restituisce il
carattere in maiuscolo, ad esempio se nella variabile x ci fosse il
carattere 'c' il risultato sarebbe 'C'. Una funzione simile è
ANSIUPPERCASE.
LOWERCASE(x): la funzione LOWERCASE restituisce il
carattere in minuscolo, ad esempio se nella variabile x ci fosse il
carattere 'B' il risultato sarebbe 'b'. Una funzione simile è
ANSILOWERCASE.
Adesso vediamo un esempio che racchiude tutte queste
funzioni appena descritte, per far si che l'esempio funzioni bisogna
dichiarare una variabile di nome carattere e di tipo char.
carattere:='C';
writeln('Carattere: ', carattere);
writeln('Valore numerico di ', carattere,': ',
Ord(carattere));
writeln('Carattere di 65: ', Chr(65));
writeln('Carattere successivo di C: ',
Succ(carattere), ' Precedente di C: ', Pred(carattere));
writeln('Uppercase di c: ', UpperCase('c'));
writeln('Lowercase di C: ', LowerCase('C'));
writeln('AnsiUppercase di c: ', AnsiUpperCase('c'));
writeln('AnsiLowercase di C: ', AnsiLowerCase('C'));
Una menzione particolare la meritano IntToStr e
StrToInt, che sono due funzioni per trasformare un numero in stringa
e viceversa. Vediamo un esempio: val:=IntToStr(7);
metterebbe nella variabile val il valore 7 sottoforma di stringa, un
carattere in questo caso, fosse stato 77 erano due caratteri. Mentre
se fosse stato: val:=StrToInt('7'); mi
avrebbe messo nella variabile val il valore numerico 7. Sono funzioni
molto utili e di uso quotidiano.
Questo blog non rappresenta una testata giornalistica poiché viene
aggiornato senza alcuna periodicità. Non può pertanto considerarsi un
prodotto editoriale ai sensi della legge n. 62/2001.
Questo sito utilizza cookie, anche di terze parti, per offriti servizi in linea con le tue preferenze. Chiudendo questo banner, scorrendo questa pagina, cliccando su un link o proseguendo la navigazione in altra maniera, acconsenti all’uso dei cookie.