Sunteți pe pagina 1din 10

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 (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:

Assign

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,

Close

EoLN

SeekEoLN

Proceduri si functii folosite la lucrul cu fisiere text 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 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. 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 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. Restrictii:

Fisierul trebuie sa fie deschis.

EoF

SeekEoF

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. 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. 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). 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, 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). 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 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:

Seek

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. 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 Reset 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.