You are on page 1of 9

Tutorial Pascal

Lucrul cu fisiere
Toate programele facute pana acum acceptau, ca sursa de date, tastatura, iar ca iesire,
monitorul. Cu toate acestea, Pascal permite folosirea fisierelor.
Sunt convins ca v-ati intrebat, cel putin o data, de ce jocurile se instaleaza cu o
multime de fisiere aditionale, in afara de executabilul propriu-zis. Raspunsul e simplu:
resursele respectivului joc se afla in acele fisiere (harti, imagini, sunete, etc).
Executabilul jocului citeste si scrie acele fisiere in functie de necesitati (scrie, de
exemplu, in fisierul de high-scores).
Sa vedem cum putem folosi si noi fisiere, in Pascal.
Pentru inceput trebuie sa stiti ca Pascal ofera trei tipuri de fisiere:

fisiere text
fisiere cu tip
fisiere fara tip

Modul de lucru (accesare, citire, scriere) difera, cel putin partial, la fiecare tip de fisier.
Sa incepem cu inceputul.

Fisiere text in Pascal (text files)


Sa presupunem ca vrem sa citim doua numere de pe prima linie a unui fisier text, si apoi matricea cu
respectivul numar de linii si coloane, dintr-un fisier text (creat cu notepad sau orice alternativa a acestuia).
Fisierul ar putea avea urmatorul continut:
1. 2 5
2. 1 2 3 4 5
3. 6 7 8 9 10
Sa vedem un program care citeste acest fisier si afiseaza datele citite pe monitor.
1. uses crt;
2. var fis: Text;
3.
lins, cols, i, j: integer;
4.
matrice: array[1 .. 20, 1 .. 20] of integer;
5. begin
6.
ClrScr;
7.
Assign(fis, 'fisier.txt');
8.
Reset(fis);
9.
10.
ReadLn(fis, lins, cols);
11.
for i := 1 to lins do
12.
begin
13.
for j := 1 to cols do
14.
Read(fis, matrice[i, j]);
15.
ReadLn(fis);
16.
end;
17.
Close(fis);
18.
19.
WriteLn('Matricea citita din fisier este:'#13#10);

20.
for i := 1 to lins do
{#13#10 = Enter}
21.
begin
{#13
= Carriage
Return}
22.
for j := 1 to cols do
{#10
= Line
Feed}
23.
write(matrice[i,j] : 3);
24.
writeln;
25.
end;
26.
Write(#13#10'Apasati orice tasta pentru a
iesi ...'#8#8#8#8);
27.
ReadKey;
{#8 =
BackSpace}
28.
end.
Declaratia unui fisier text se face identic cu declararea unei variabile obisnuite, iar tipul variabilei este
Text..
Sa vedem ce proceduri si functii avem la dispozitie pentru lucrul cu fisiere text.
Proceduri si functii folosite la lucrul cu fisiere text
Nume
Descriere
Asigneaza un fisier (definit prin calea catre el) catre o variabila de tip fisier. Toate operatiile
ulterioare care folosesc acel fisier vor utiliza variabila acestuia. Asocierea dintre variabila si
respectivul fisier va exista pana la urmatoarea asignare a variabilei catre alt fisier.
Calea catre fisier trebuie sa fie o cale definita prin 0 sau mai multe directoare, separate prin
semnul backslash \, urmate de numele complet al fisierului. Daca aceasta cale este inceputa
direct cu semnul backslash, atunci este folosita ca si cum ar fi inceput direct in radacina (
C:\Folder\fisier.txt este identic cu \Folder\fisier.txt, daca programul este rulat dintr-un director
de pe C:. Daca este dat doar numele fisierului, atunci fisierul este cautat in directorul curent
Assign
(cel
de
unde
este
rulat
programul).
Numele fisierului trebuie sa se conformeze standardului DOS de denumire a fisierelor, adica
8.3 (nume de maxim 8 caractere, fara spatii, si extensie (optionala) de maxim 3 caractere.
Un caz special este cel in care calea catre fisier este sirul vid (adica '' - doua apostroafe, unul
dupa celalalt). In acest caz, variabila de fisier este asignata intrarii / iesirii standard. Dupa o
asignare a variabilei catre sirul vid, folosirea procedurii Reset va asocia variabila catre intrarea
standard, iar folosirea procedurii ReWrite va asocia aceasta variabila cu iesirea standard.
Restrictie:
procedura Assign nu poate fi folosita pe un fisier deja deschis.
Deschide un fisier existent pentru citire. Daca fisierul nu exista, aceasta procedura va genera o
eroare.
Dupa ce fisierul a fost deschis, pozitia in fisier (file pointer-ul) este setata la inceputul acestuia
Reset
(de
acolo
poate
incepe
citirea).
Daca variabila de fisier a fost asignata unui sir vid, dupa apelul acestei proceduri, variabila de
fisier se va referi la intrarea standard (tastatura, de obicei).
Creaza un fisier nou si il deschide pentru scriere. Daca fisierul exista, atunci el este sters si
recreat (gol). Daca variabila de fisier este asignata unui fisier deschis, acesta va inchis, sters,
recreat
si
redeschis.
Rewrite Dupa ce fisierul a fost deschis, pozitia in fisier (file pointer) este setata la inceputul acestuia.
Daca variabila de fisier a fost asignata unui sir vid, dupa apelul acestei proceduri, variabila de
fisier se va referi la iesirea standard (monitorul, de obicei).
Append Deschide fisierul ales (prin folosirea procedurii Assign) pentru scriere. Daca fisierul nu exista,
atunci aceasta procedura va genera o eroare. Daca fisierul este deja deschis, atunci el este
inchis si redeschis. Pozitia in fisier (file pointer) este setata la sfarsitul acestuia.
Daca variabila de fisier a fost asignata unui sir vid, dupa apelul acestei proceduri, variabila de

Proceduri si functii folosite la lucrul cu fisiere text


fisier se va referi la iesirea standard (monitorul, de obicei).
Inchide fisierul desemnat de variabila de fisier, daca respectivul fisier a fost deschis folosind
una
din
procedurile
Reset,
Rewrite
sau
Append.
Close
Fisierul asociat cu variabila de fisier este adus la zi cu toate modificarile operate asupra lui,
inainte de a fi inchis.
Aceasta functie (acronim de la End of LiNe) returneaza True daca pozitia in fisier (file
pointer-ul) este la sfarsitul unei linii (marcaj #13#10) sau la sfarsitul fisierului. Returneaza
EoLN False
in
caz
contrar.
Functia poate fi apelata fara parametru sau cu un parametru de tip Text (fisier text). Daca este
apelata fara parametru, atunci fisierul este considerat a fi fisierul standard de intrare (tastatura).
Verifica daca mai sunt date pe linia curenta, de la pozitia curenta pana la sfarsitul liniei. Daca
nu mai sunt date pana la sfarsitul liniei (doar spatii sau tab-uri), va returna True, returnand
False in caz contrar.
SeekEoLN Restrictii:
Fisierul trebuie sa fie deschis.
Poate fi folosita doar cu fisiere text.
Aceasta functie (acronim de la End of File) returneaza True daca pozitia in fisier (file
pointer) este la sfarsitul fisierului. Returneaza False in caz contrar.
EoF
Functia poate fi apelata fara parametru sau cu un parametru de tip Text (fisier text). Daca este
apelata fara parametru, atunci fisierul este considerat a fi fisierul standard de intrare (tastatura).
Verifica daca mai sunt date in fisier, de la pozitia curent pana la sfarsitul fisierului. Daca nu
mai sunt date pana la sfarsitul fisierului (doar spatii sau tab-uri), va returna True, returnand
False in caz contrar.
SeekEoF Restrictii:
Fisierul trebuie sa fie deschis.

Poate fi folosita doar cu fisiere text.

Daca ati trecut prin explicatiile date in tabelul de mai sus, ar trebui sa stiti destul de multe pentru a folosi
un fisier text fara probleme.
Sa vedem un mic program care citeste prima linie dintr-un fisier text si o adauga, inversata, la sfarsitul
fisierului.
1. uses crt;
2. var fis: Text;
3.
linie: String;
4.
i: integer;
5.
c: Char;
6. begin
7.
ClrScr;
8.
Assign(fis, 'fisier.txt');
9.
Reset(fis);
10.
11.
ReadLn(fis, linie);
12.
WriteLn('Prima linie din fisier este urmatoarea:');
13.
WriteLn(linie+#13#10);
14.
15.
WriteLn('Vom adauga linia, inversata, in fisier, la
sfarsitul acestuia.');
16.
WriteLn;
17.
18.
for i := 1 to Length(linie) div 2 do {bucla aceasta
inverseaza sirul de caractere}
19.
begin
20.
c := linie[i];

21.
linie[i] := linie[Length(linie) - i + 1];
22.
linie[Length(linie) - i + 1] := c;
23.
end;
24.
25.
Append(fis);
26.
WriteLn(fis, #13#10 + linie);
27.
Close(fis);
28.
Write(#13#10'S-a facut ! Apasati orice tasta pentru a
iesi ...');
29.
ReadKey;
30.
end.
Ultimul program care va folosi fisiere text in acest tutorial va citi date dintr-un fisier si le va salva in alt
fisier.
1. uses crt;
2. var fis: Text;
3.
linie: String;
4.
i: integer;
5.
c: Char;
6. begin
7.
ClrScr;
8.
Assign(fis, 'fisier.in');
9.
Reset(fis);
10.
11.
ReadLn(fis, linie);
12.
Close(fis);
13.
14.
WriteLn('Prima linie din fisier este urmatoarea:');
15.
WriteLn(linie+#13#10);
16.
17.
Assign(fis, 'fisier.out');
18.
Rewrite(fis);
19.
WriteLn(fis, linie);
20.
Close(fis);
21.
22.
Write(#13#10'S-a facut ! Apasati orice tasta pentru a
iesi ...');
23.
ReadKey;
24.
end.
Atentie: presupun ca este evident ca toate fisierele de intrare folosite in aceste programe vor trebui create
manual inainte de pornirea programului.

Fisiere cu tip in Pascal (typed files)


Acum, dupa ce-ati aflat ce-i cu fisierele text in Pascal, o sa-mi spuneti ca jocurile pe care le mentionam
mai sus nu folosesc fisiere text, sau foarte rar... si nu va pot contrazice. Asa este.
Fisierele text, desi permit salvarea a orice date in ele, sunt limitate de faptul ca nu ne permit citirea unui
anumit caracter, decat daca am citit toate caracterele dinaintea lui. Imaginati-va un fisier text de cativa
megabytes (mega-octeti, daca vreti ), din care vrem sa citim caracterul cu indicele 1.123.194 ... va
trebui sa citim un milion de caractere inainte de a putea citi caracterul care ne intereseaza.
Aici intra in joc fisierele cu tip. Ele permit citirea secventiala a datelor (ca si fisierele text), dar si citirea

aleatorie (random) din fisier. Spre deosebire de fisierele text, de unde puteam citi doar siruri de caractere
(nu va lasati pacaliti de faptul ca ReadLn citeste si numere ... le converteste intern din string in valoare
numerica !), din fisiere fara tip se pot citi doar valori de acelasi tip ca si fisierul in sine.
Fisierele cu tip sunt, practic, o varianta a vectorilor (array, if you please). Pot stoca date de un singur tip,
cel setat in declararea variabilei de fisier, dar sunt limitate de spatiul disponibil pe hard-disk (si, in
versiunile vechi de Pascal, cum ar fi Borland Pascal, de o marime maxima de 2 GB / fisier - tineti totusi
cont ca in 1992, cand a aparut Borland Pascal 7.0 nu sunt sigur daca existau, inca, hard-disk-uri atat de
mari !).
Haideti sa vedem un mic program care scrie un set de date aleatorii intr-un fisier cu tip (tip integer, pentru
inceput), iar apoi le reciteste si afiseaza a 20-a valoare din fisier.
1. uses crt;
2. var fis: file of integer;
3.
i, val: integer;
4. begin
5.
ClrScr;
6.
Randomize;
7.
Assign(fis, 'fisier.bin');
8.
Rewrite(fis);
9.
10.
for i := 1 to 100 do
11.
begin
12.
val := Random(20000) + 1; {valori intre 1 si 20000}
13.
Write(fis, val);
14.
end;
15.
Close(fis);
16.
17.
Assign(fis, 'fisier.bin');
18.
ReSet(fis);
19.
Seek(fis, 19); {indexul incepe de la 0}
20.
21.
Read(fis, i);
22.
WriteLn('A 20-a valoare din fisier este : ',i);
23.
24.
Close(fis);
25.
26.
Write(#13#10'S-a facut ! Apasati orice tasta pentru a
iesi ...');
27.
ReadKey;
28.
end.
Este de remarcat faptul ca fiecare element din fisier ocupa 2 bytes, in acest caz (integer).
Lista de proceduri si functii care pot fi folosite la manipularea fisierelor cu tip sunt date in tabelul
de mai jos. Explicatiile date in acest tabel sunt doar complementare celor date in tabelul de
proceduri si functii dat pentru folosirea cu fisiere text.
Proceduri si functii folosite la lucrul cu fisiere cu tip
Nume
Descriere
Assign Identic cu fisierele text.
Deschide un fisier existent (pentru citire / scriere). Daca fisierul nu exista, aceasta procedura va
genera o eroare.
Reset Dupa ce fisierul a fost deschis, pozitia in fisier (file pointer-ul) este setata la inceputul acestuia.
Daca variabila de fisier a fost asignata unui sir vid, dupa apelul acestei proceduri, variabila de
fisier se va referi la intrarea standard (tastatura, de obicei).
Rewrite Creaza un fisier nou si il deschide (pentru scriere / citire). Daca fisierul exista, atunci el este
sters si recreat (gol). Daca variabila de fisier este asignata unui fisier deschis, acesta va inchis,

Proceduri si functii folosite la lucrul cu fisiere cu tip


sters, recreat si redeschis.
Dupa ce fisierul a fost deschis, pozitia in fisier (file pointer) este setata la inceputul acestuia.
Daca variabila de fisier a fost asignata unui sir vid, dupa apelul acestei proceduri, variabila de
fisier se va referi la iesirea standard (monitorul, de obicei).
Inchide fisierul desemnat de variabila de fisier, daca respectivul fisier a fost deschis folosind una
din procedurile Reset sau Rewrite.
Close
Fisierul asociat cu variabila de fisier este adus la zi cu toate modificarile operate asupra lui,
inainte de a fi inchis.
Returneaza numarul de componente din fisierul desemna de variabila de fisier. Marimea actuala
a fisierului poate fi aflata inmultind rezultatul acestei functii cu numarul de bytes folositi de
fiecare componenta.
FileSize Restrictii:
Fisierul trebuie sa fie deschis.
Nu poate fi folosita cu fisiere text.
Returneaza pozitia in fisier (file pointer-ul).
Daca pozitia este chiar la inceputul fisierului, atunci aceasta functie returneaza 0. Daca pozitia
este la sfarsitul fisierului, atunci rezultatul lui FilePos este egal cu cel al functie FileSize,
prezentata mai sus.
FilePos

Seek

Restrictii:
Fisierul trebuie sa fie deschis.
Nu poate fi folosita cu fisiere text.
Muta pozitia in fisier (file pointer) la cea specificata. Urmatoarea citire sau scriere se face din
acel loc.
Numarul primei componente din fisier este 0. Noua pozitie care poate fi specificata este de tip
Longint, deci nu poate merge mai departe de 2 GB. Pentru a scrie la sfarsitul fisierului (dupa
ultima componenta) se poate folosi cu impreuna cu rezultatul functiei FileSize.
Daca pozitia este chiar la inceputul fisierului, atunci aceasta functie returneaza 0. Daca pozitia
este la sfarsitul fisierului, atunci rezultatul lui FilePos este egal cu cel al functie FileSize,
prezentata mai sus.
Restrictii:
Fisierul trebuie sa fie deschis.

Nu poate fi folosita cu fisiere text.


Trunchiaza fisierul de la pozitia curenta in fisier (file pointer). Toate componentele de dupa
pozitia actuala in fisier sunt sterse.
Restrictii:
Truncate
Fisierul trebuie sa fie deschis.

Nu poate fi folosita cu fisiere text.

Niciodata nu mi-a placut restrictia care spunea ca aceasta procedura / functie nu poate fi folosita cu fisiere text, asa ca am cautat
o solutie. Solutia evidenta este sa folositi un fisier cu componente de tip Char (practic, text), putand astfel folosi si functii gen
FileSize, FilePos, Seek, Truncate. Totusi, probabil ca ati vrea sa aveti grija la sfarsiturile de linie / fisier

Fisiere fara tip in Pascal (untyped files)


Fisierele fara tip pot fi privite ca niste fisier cu tip byte, cu diferenta ca datele din aceste fisiere nu pot fi
citite/scrise cu procedurile obisnuite (Read, Write), folosind BlockRead/BlockWrite, pentru transferuri la
viteza mare.
Sa vedem ce s-a modificat si ce s-a adaugat, din punct de vedere al instructiunilor care pot fi folosite.
Proceduri si functii folosite la lucrul cu fisiere cu tip
Nume

Descriere

Assign Identic cu fisierele cu tip.


Reset In cazul fisierelor fara tip, aceasta procedura accepta si un parametru de tip Word, care specifica
numarul de bytes avut de o componenta din fisier (RecSize). In mod implicit, RecSize este egal

Proceduri si functii folosite la lucrul cu fisiere cu tip


cu 128. Este preferabil sa il setati pe 1, avand astfel control absolut asupra citirilor / scrierilor
facute
in
fisier.
Formatului apelului acestei proceduri este urmatorul:
1. Reset(var F: File[; RecSize: Word]);
In cazul fisierelor fara tip, aceasta procedura accepta si un parametru de tip Word, care specifica
numarul de bytes avut de o componenta din fisier (RecSize). In mod implicit, RecSize este egal
cu 128. Este preferabil sa il setati pe 1, avand astfel control absolut asupra citirilor / scrierilor
Rewrite
facute in fisier.
Formatului apelului acestei proceduri este urmatorul:
1. Rewrite(var F: File[; RecSize: Word]);
Fisiere text, Probleme

1. Sa se scrie un program care calculeaza elementele multimilor AUB si A\B.


Program P1;
var a,b,c:set of byte;
f:text;
i:byte;
begin
assign(f,'in.txt');
reset(f);
a:=[];
while not eoln(f) do
begin
read(f,i);
a:=a+[i];
end;
readln(f);
b:=[];
while not eoln(f) do
begin
read(f,i);
b:=b+[i];
end;
close(f);
c:=a+b;
for i:=0 to 255 do
if i in c then write(i,' ');
writeln;
c:=a-b;
for i:=0 to 255 do
if i in c then write(i,' ');
end.

2. De scris un subprogram care afiseaza modalitatea de plata, folosind


un numar minim de bancnote, a unei class="style35">sume S de lei.

Numarul de bancnote si valoarealor se citeste in fisierul text


bani.in, care contine pe fiecare linie cite 2 valori:
prima indica valoarea bancnotei si a doua
numarul de bancnote cu valoarea data..
Program P2;
var a,b,num:array[1..7] of integer;
s,i:integer;

f:text;
begin
assign(f,'bani.in');reset(f);
for i:=1 to 7 do readln(f,a[i],b[i]);
close(f);
write('s=');readln(s);
for i:=7 downto 1 do
begin
num[i]:=s div a[i];s:=s mod a[i];
if num[i]>b[i] then begin s:=s+(num[i]-b[i])*a[i];num[i]:=b[i];
end;
end;
if s<>0 then
writeln('Nu este posibil de efectuat plata cu bancnotele
respective!')
else begin
writeln('Suma este achitata cu urmatoarele bancnote:');
for i:=7 downto 1 do if num[i]<>0 then
writeln(a[i],'-',num[i]);
end;
end.

3. Sa se scrie un program care contine cuvintele textului in ordine alfabetica


si numarul lor de aparitii.
Program P3;
var
f:text;
a:array[1..100] of string;
s:string;
i,k,n:byte;
begin
assign(f,'Intrare.txt');reset(f);
i:=1;
while not eof(f) do
begin
readln(f,s);s:=s+' ';
while pos(' ',s)<>0 do
begin
a[i]:=copy(s,1,pos(' ',s)-1);delete(s,1,pos(' ',s));
i:=i+1;
end;
end;
close(f);
n:=i-1;
{Sortarea cuvintelor in ordine alfabetica}
for k:=1 to n-1 do
for i:=1 to n-1 do
if a[i]>a[i+1] then
begin
s:=a[i];a[i]:=a[i+1];a[i+1]:=s;
end;
{Determinarea numarului de aparitii al fiecarui cuvint}
assign(f,'Iesire.txt');rewrite(f);
k:=1;
for i:=1 to n-1 do
if a[i]=a[i+1] then k:=k+1
else
begin
writeln(f,a[i],' ',k);
k:=1;
end;
writeln(f,a[n],' ',k);
close(f);
end.

Probleme rezolvate fiiere text


1.Se d fiierul text numere.txt care conine pe primul rnd o valoare natural nenul n (n<=30000) i pe
al doilea rnd n valori ntregi de cel mult 4 cifre separate prin unul sau mai multe spaii. Se cere s se
calculeze suma elementelor pare de pe al doilea rnd din fiier.
var f:text;
begin
n,i,s,x:integer;
read(f,x);
begin
if x mod 2=0 then s:=s+x
assign(f,numere.txt);
end;
reset(f);
writeln(Suma este: ,s);
readln(f,n);
close(f)
s:=0;
end.
for i:=1 to n do
2.Se d fiierul text numere.txt care conine pe primul rnd o valoare natural nenul n (n<=30000) i pe
urmtoarele n rnduri n valori ntregi de cel mult 4 cifre, cte o valoare pe un rnd. Se cere s se calculeze
i s se afieze media aritmetic a elementelor pozitive dintre cele n valori din fiier.
var f:text;
n,i,s,x,nr:integer;
begin
assign(f,numere.txt);
reset(f);
readln(f,n);
s:=0; nr:=0;
for i:=1 to n do
begin
readln(f,x);
if x>0 then

begin
s:=s+x;
nr:=nr+1;
end;
end;
if nr<>0 then writeln(Media aritmetica este:
,s/nr:2:2)
else writeln(Nu exista valori pozitive in
fisier);
close(f)
end.

3.Se citete de la tastatur o valoare natural nenul n (n<=30000), apoi n valori ntregi de cel mult 4 cifre.
Se cere s se afieze n fiierul date.out valorile impare. Valorile se vor scrie pe un singur rnd separate
printr-un spaiu. (Problem rezolvat la tabl de Brle Dan)
var f:text;
n,i,x:integer;
begin
assign(f,date.out);
rewrite(f);
write(n=); readln(n);
for i:=1 to n do

begin
write(x=); readln(x);
if x mod 2=1 then write(f,x, )
end;
close(f)
end.

You might also like