Sunteți pe pagina 1din 19

STRUCTURI DE DATE - Curs 2 1

CURS 2. - STRUCTURI DE DATE

5. FIŞIERE

Structurile prezentate în cursul anterior se remarcă prin faptul că datele lor sunt stocate în
memoria internă (volatilă) a computerului. La închiderea progr
amului, memoria alocată se elibera şi astfel datele se pierdeau. Există însă situaţii în care un program
trebuie să lucreze cu mai multe seturi de date folosite anterior, numite fişiere. Pentru aceste situaţii există
o structură de tip fişier care stochează datele în permanenţă pe un suport extern (din memoria externă).
Astfel, de exemplu dacă dorim să scriem un program pentru un concurs de admitere va fi util să stocăm în
fişiere datele introduse în memorie pentru a le putea folosi şi altă dată. Lucrul aceste necesar pentru că
concursul se desfăşoară pe parcursul a mai multor zile.
Noţiunea de fişier se foloseşte cu înţelesul de colecţie de date sub formă de text sau sub formă
binară, date care pot fi citite sau scrise de către un program, aflate în memoria extern ă a computerului
(HDD, FDD, CD, Bandă magnetică).
Fişierul este unitatea de bază a sistemului de operare pentru organizarea datelor. Sistemele
de operare folosesc două tipuri de fişiere: fişiere text şi fişiere binare. Aceste tipuri de fişiere pot fi
prelucrate folosind programe scrise în diferite limbaje de programare. Limbajele de programare
oferă suport de prelucrare pentru aceste tipuri de fişiere. De exemplu, în Pascal avem fişiere text şi
fişiere fără tip iar în C avem fişiere text şi fişiere binare. Vom discuta din punct de vedere al
structurilor de date aceste tipuri de fişiere.
Indiferent de limbajul de prelucrare, programul de prelucrare pentru fişiere trebuie să parcurgă
obligatoriu următorii paşi:
a. deschiderea fişierului.
b. Prelucrarea propiu-zisa care constă în poziţionarea pe o anumită înregistrare su un anume
octet, citirea sau scrierea de date în fişier.
c. Închiderea fişierului.

5.1. Tipuri de fişiere în limbajul Pascal

a) Din punctul de vedere al structurii există trei tipuri de fişiere în limbajul Turbo Pascal:
fişiere text, fişiere cu tip şi fişiere fără tip.

Fişierele text se declară în felul următor:


var f: text;
Fişierele text sunt fişiere formate din linii de text de lungime variabilă separate între ele prin
marcaje de sfârşit de linie. Aceste marcaje de sfârşite de linie sunt formate din perechea de caractere CR (
Carriage return - revenire la început de rând) şi LF (Line Feed - avans la rândul următor).
Observaţie - fişierele standard de intrare/ieşire (tastatura, respectiv monitorul) sunt fişiere text.

Fişierele cu tip se declară în felul următor:


var f:file of tip_de_bază
Fişierele cu tip sunt fişiere care conţin un anumit număr de componente toate de acelaşi tip
(standard sau definit de utilizator, simplu sau structurat).
2 Curs 1 - STRUCTURU DE DATE

Fişierele fără tip sunt fişiere la care nu se face o precizare asupra naturii informaţiei conţinută în
fişier şi se declară în felul următor:
var f:file;
Observaţie - orice fişier poate fi tratat ca un fişier fără tip.

b) Din punctul de vedere al modului de acces la informaţia conţinută în fişier acestea pot fi de
două tipuri: fişiere cu acces secvenţial şi fişiere cu acces direct.
Fişierele cu acces secvenţial sunt acele fişiere la care accesul la componentele sale poate fi făcut
numai în ordinea în care acestea apar în cadrul fişierului. De exemplu pentru a putea citi componenta a
şaptea din fişier trebuiesc citite în prealabil primele şase componente.
Fişierele cu acces direct sunt acele fişiere la care accesul se poate face direct la orice
componentă din cadrul fişierului, în prealabil însă trebuie precizat numărul de ordine al componentei care
se doreşte a fi prelucrată.

5.2. Subprograme standard pentru lucrul cu fişiere

Indiferent de tipul unui fişier variabila fişier f trebuie asociată cu un fişier fizic, extern prin
apelul procedurii ASSIGN. Utilizând sintaxa:
assign(f,nume_fişier)
se realizează asocierea dintre variabila de tip logic f (declarată în program) şi numele fişierului de pe
suportul magnetic. De exemplu, să presupunem că într-un program dorim să lucrăm cu fişierul date.txt,
care conţine datele de intrare pentru programul în cauză. Pentru a putea face acces la acest fişier de date,
în primul rând trebuie declarată în program variabila fişier f (var f:text - spre exemplu) iar apoi, pentru
ca această variabilă să fie asociată fişierului date.txt, trebuie apelată procedura ASSIGN în felul următor:
assign(f,’date.txt’)

În continuare, în program se va lucra cu variabila f, dar de fapt programul face referire la


fişierul date.txt, până la o eventuală reasignare a lui f.

5.3. Subprograme utilizate la deschiderea fişierelor

Operaţiile care se efectuează asupra unui fişier sunt de citire şi scriere, exact ca şi operaţiile care
se efectuează cu tastatura/ecranul unui sistem de calcul, acestea fiind de fapt tot fişiere. Înainte de a lucra
cu un fişier trebuie precizat modul în care se lucrează cu el (citire, scriere, citire şi scriere)
REWRITE(f) - este procedura standard care se utilizează atunci când se doreşte crearea unui
fişier nou. Procedura are următorul efect: pregăteşte fişierul f pentru scriere înlocuindu-l cu un fişier vid
(care nu conţine nici o componentă) şi stabileşte poziţia iniţială de scriere. Dacă fişierul respectiv există
deja el va fi şters şi va fi creat unul nou.
RESET(f) - este procedura standard care se utilizează atunci când se doreşte să se lucreze cu un
fişier existent (în general se utilizează pentru a putea citi dintr-un fişier). Procedura are următorul efect:
deschide fişierul f şi stabileşte poziţia iniţială de prelucrare pe prima componentă din fişier, ca în figura de
mai jos:

f . . .

poziţie de prelucrare
STRUCTURI DE DATE - Curs 2 3

READ este procedura cu ajutorul căreia se poate citi dintr-un fişier. Se apelează în felul următor:
read (f,v1,v2,…,vn)
şi are ca efect citirea variabilelor v1,v2,…,vn din fişierul f. Efectul procedurii este ilustrat în figura
următoare:
-înainte de apelul procedurii READ:

. . .
f x v

poziţie de prelucrare

-după apelul procedurii READ(f,v):


. . .
f v x

poziţie de prelucrare

Procedura WRITE este utilizată pentru a putea scrie într-un fişier. Se apelează în felul următor:
write (f,e1,e2,…,en) ,
şi are ca efect scrierea în fişier în poziţia curentă de scriere a expresiilor e1,e2,…,en. Efectul procedurii este
ilustrat în figura următoare:

-înainte de apelul procedurii WRITE: -după apelul procedurii WRITE(f,x):

f f x

poziţie de prelucrare
poziţie de prelucrare

CLOSE(f) este procedura standard utilizată la închiderea unui fişier. Procedura close se apelează
la sfârşit, când operaţiile de citire/scriere s-au încheiat.
Funcţia EOF(f) este o funcţie cu rezultat de tip boolean şi are valoarea TRUE dacă s-a ajuns la
sfârşitul de fişier (poziţia de prelucrare este după ultima componentă din fişier) şi valoarea FALSE în caz
contrar.
Aceste proceduri şi funcţii standard sunt valabile la toate tipurile de fişiere. În continuare se vor
prezenta şi diferenţele care există între cele trei tipuri de fişiere cu care lucrează limbajul Pascal.
5.3.1. Fişiere cu tip

Fişierele cu tip sunt acele fişiere care au toate componentele de acelaşi tip (standard sau definit de
utilizator). Ele se declară în felul următor:
type fisier=file of tip_de_bază
sau, în cazul în care nu se dă un nume tipului fişier:
var f: file of tip_de_bază
Fiecare componentă dintr-un fişier cu tip are asociat un număr de ordine cuprins între 0 şi
numărul total de componente - 1.
4 Curs 1 - STRUCTURU DE DATE

În cazul fişierelor cu tip, datorită faptului că toate componentele sunt de acelaşi tip se poate
face şi accesul direct la acestea. În acest caz există şi subprograme standard specifice fişierelor cu
tip:

a) Procedura SEEK permite poziţionarea indicatorului de înregistrări pe o anumită componentă


din fişier. Se apelează în felul următor:
seek(f,poziţie)
unde poziţie reprezintă numărul de ordine asociat componentei la care se doreşte să se facă accesul
(componenta care uirmează să fie prelucrată).
b) Funcţia FILESIZE(f) este o funcţie care are rezultat de tip întreg şi care reprezintă numărul
total de componente din fişierul f (dimensiunea fişierului).
c) Funcţia FILEPOS(f) este o funcţie cu rezultat de tip întreg şi care reprezintă numărul de
ordine al componentei care urmează să fie prelucrată.
d) Procedura TRUNCATE(f) este o procedură care are ca efect trunchierea fişierului f prin
îndepărtarea grupului final de componente începând cu cea curentă.
Observaţii:
- în cazul fişierelor cu tip se pot face atât operaţii de citire din fişier cât şi operaţii de scriere în
fişier indiferent de modul în care a fost deschis fişierul (utiliizând procedura REWRITE sau utilizând
procedura RESET).
- un avantaj deosebit al folosirii fişierelor cu tip este modul în care se citesc/scriu
componentele. Spre deosebire de citirea de la tastatură, sau afişarea pe monitor unde datele de
tip structurat se citesc/scriu numai componentă cu componentă, în cazul fişierelor cu tip citirea/scrierea
datelor de tip structurat se poate face integral, indiferent de tipul componentelor. Este prezentat în acest
sens ca exemplu un program care crează un fişier care conţine date despre studenţi. Programul afişează pe
ecran datele despre studenţii dintr-o grupă.
Program date_studenti;
type student=record
nume:string[25];
adresa:string[30];
tel:string[10];
grupa:integer;
end;
var f:file of student;
r:char;
e:student;n:integer;
procedure creare;
begin
assign(f,'student.dat');
rewrite(f);
repeat
write('nume:');readln(e.nume);
write('adresa:');readln(e.adresa);
write('telefon');readln(e.tel);
write('grupa');readln(e.grupa);
write(f,e);
writeln('continuati (d/n)?');readln(r);
STRUCTURI DE DATE - Curs 2 5

until r='n';
end;
procedure afisare;
var c:integer;
begin
reset(f);
write('introduceti grupa pt care doriti lista:');readln(c);
writeln(' numele si prenumele adresa telefon');
while not eof(f) do
begin
read(f,e);
if e.grupa=c then
writeln(e.nume:20,e.adresa:30,e.tel:10);
end;
close(f);
end;
begin
creare;
afisare;
readln;
end.
5.3.2. Fişiere text

Fişierele text sunt fişiere care conţin caractere şi marcatoare de sfârşit de linie. Caracterele sunt
structurate pe linii iar liniile sunt separate între ele prin marcatoarele de sfârşit de linie. Se declară în felul
următor:
var f:text
Marcatoarele de sfârşit de linie sunt formate din perechea de caractere de control: CR(carriage
return) şi LF(line feed). Acest marcator de sfârşit de linie nu poate fi atribuit unei variabile de tip CHAR
dar poate fi citit sau scris cu ajutorul următoarelor proceduri standard:
WRITELN(f) o procedură care are ca efect înscrierea unui marcator de sfârşit de linie în fişierul
f.
READLN(f) o procedură care are ca efect citirea unui marcator de sfârşit de linie din fişierul f,
adică determină poziţionarea indicatorului de citire la începutul liniei următoare din fişierul f.

Alte proceduri şi funcţii standard care sunt valabile numai la fişierele text

Funcţia EOLN(f) este o funcţie care detectează sfârşitul de linie, furnizând rezultatul TRUE dacă
următorul element din fişierul f este marcatorul de sfârşit de linie şi FALSE în caz contrar.
Funcţia SEEKEOLN(f) are rezultat boolean şi anume valoarea TRUE dacă în fişierul f între
poziţia curentă de prelucrare şi următorul marcaj de sfârşit de linie există numai caractere spaţiu şi/sau
TAB. Dacă în această zonă există cel puţin un alt caracter rezultatul furnizat este FALSE.
Funcţia SEEKEOF(f) are rezultat de tip boolean şi anume valoarea TRUE dacă între poziţia
curentă de prelucrare şi sfârşitul de fişier există numai caractere spaţiu, TAB şi/sau marcaje de sfârşit de
linie. Dacă în această zonă există cel puţin un alt caracter funcţia returnează valoarea FALSE.
6 Curs 1 - STRUCTURU DE DATE

Observaţii:
Toate subprogramele standard prezentate la fişierele text sunt valabile numai la acest tip de fişiere
Fişierele standard de intrare/ieşire şi anume tastatura, respectiv monitorul sunt fişiere text.
Fişierele text au particularitatea că permit un singur fel de operaţie asupra lor în funcţie de modul în care
au fost deschise: scriere, dacă fişierul a fost deschis cu ajutorul procedurii REWRITE sau APPEND
respectiv citire în cazul deschiderii cu ajutorul procedurii RESET.
Procedura APPEND(f) este o procedură care permite deschiderea unui fişier existent în vederea
adăugării de noi linii la sfîrşitul său. Efectul acestei proceduri este deci următorul: se va deschide fişierul
f iar poziţia de scriere va fi stabilită automat după ultima componentă (linie) din fişier.
În continuare este prezentat un program care permite crearea unui fişier text prin citirea de la
tastatură a unui text, care se încheie cu o linie vidă.

Program creare_fisier_text;
var f:text;
s:string;
begin
assign(f,'fis_text.txt');
rewrite(f);
repeat
readln(s);
writeln(f,s)
until s='';
close(f);
end.
Exemplul de mai jos permite afişarea pe ecran a conţinutului unui fişier, fişier al cărui nume va fi
citit de la tastatură. Programul permite şi oprirea afişării şi aşteaptă apăsarea tastei ENTER dacă fişierul
conţine mai multe linii şi nu încape pe un ecran.

program afisare_fisier_text;
var f:text;
s,nume:string;
i:integer;
begin
writeln('introduceti numele fisierului:');readln(nume);
assign(f,nume);
reset(f);
while not eof(f) do
begin
readln(f,s);
writeln(s);
i:=i+1;
if i mod 22 = 0 then readln;
end
close(f);
end.
STRUCTURI DE DATE - Curs 2 7

5.3.3. Fişiere fără tip.

În cazul fişierelor fără tip asupra structurii informaţiei din fişier nu se face nici un fel de
precizare. Se declară în felul următor:
var f:file
La fiecare operaţie de citire/scriere se transferă între memorie şi fişier (suportul de memorie
externă) un bloc de informaţie cu o anumită dimensiune în număr de octeţi. Dimensiunea acestui bloc se
specifică de către programator pentru fiecare transfer în parte ca număr de blocuri elementare.
Dimensiunea unui bloc elementar se specifică o singură dată (ca număr de octeţi elementari) la
deschiderea fişierului în felul următor:
rewrite (f, dim_bloc_elementar),
sau:
reset (f, dim_bloc_elementar)
Procedurile care realizează operaţiile de citire/scriere în cazul fişierelor fără tip sunt următoarele:
blockread (f, buffer, număr, rezultat),
şi
blockwrite (f, buffer, număr, rezultat)
unde:
- Buffer este o variabilă suficient de mare în/din care se face citirea/scrierea informaţiei;
- număr reprezintă numărul de blocuri elementare care se transferă;
- rezultat este un parametru opţional de tip întreg şi care are ca valoare numărul de blocuri efectiv
transferate în urma execuţiei operaţiei de citire/scriere. Dacă transferul a fost realizat integral trebuie ca
număr=rezultat.
Observaţii:
- La fel ca şi în cazul fişierelor cu tip se pot folosi subprogramele standard SEEK, FILESIZE,
FILEPOS, acestea lucrând cu componente bloc elementar;
- Orice fişier poate fi prelucrat ca fişier fără tip indiferent de modul în care a fost creat sau de
modul în care va fi exploatat ulterior.
- Principalul avantaj al fişierelor fără tip este rapiditatea transferului, mai ales în cazul în care se
lucrează cu blocuri elementare de dimensiune mare.
Prezentăm în continuare un exemplu de program care realizează o copie a unui fişier al cărui
nume se citeşte de la tastatură. În acest exemplu s-a ales dimensiunea unui bloc elementar de 1 octet iar
variabila Buffer s-a declarat ca fiind un tablou de caractere pentru a corespunde acestei dimensiuni de
bloc elementar.
Program fisiere_fara_tip;
var numes,numed:string;
fs,fd:file;
buffer:array[1..1024] of char;
rezc,rezs,numar:integer;
begin
write('nume fisier sursa:');readln(numes);
write('nume fisier destinatie:');readln(numed);
reset(fs,1);rewrite(fd,1);
repeat
blockread(fs,buffer,numar,rezc);
if rezc>0 then
8 Curs 1 - STRUCTURU DE DATE

blockwrite(fd,buffer,rezc,rezs);
until (rezc=0) or (rezc<>rezs);
close(fs);close(fd); end.
Exemple de prelucrare a fişierelor text.

1. Crearea fişierului text:


Ex: Creaţi un fişier text ce va păstra informaţiile despre studenţii unei grupe: Nume, Prenume, Mg
(media generală).

PROCEDURE Creare;
VAR F: text;
Nume,Prenume: string [20] ; Mg: real; Răsp: string[2];
BEGIN
Assign (F, ‘ Studenţi.txt’);
Rewrite(F);
Repeat
Write(‘ Nume student: ’);
Readln(Nume);
Write(‘ Prenume student: ’);
Readln(Prenume);
Write(‘ Media : ’);
Readln(Mg);
Writeln(F, Nume ,’ ‘, Prenume ,’ ‘, Mg:5:2);
Writeln(‘Mai aveti studenţi (DA / NU) ? ‘);
Readln(Răsp);
Until Răsp = ‘NU’;
Close(F);
END;

2. Afişarea oricărui fişier text :

PROCEDURE Afişare;
VAR F: text; Linie : string;
BEGIN
Assign (F, ‘ Studenţi.txt’);
Reset(F);
While not EOF (F) do
Begin
Readln(F, Linie);
Write(Linie);
End;
Close(F);
END;

Sau

procedure Afisare( NumeFis:String);


Var F:Text;
Linie :string;
I:Word;
begin
Assign(F,NumeFis);
Reset(F);
I:=0;
repeat
ReadLn(F,Linie);
WriteLn(Linie);
STRUCTURI DE DATE - Curs 2 9

I:=I+1;
if I=20 then
begin
ReadLn;
ClrScr;
I:=0;
end;
until eof(F);
Close(F);
end.

3. Adăugarea unei linii noi în fişier :

PROCEDURE Adăugare;
VAR F: text;
Nume,Prenume: string [20] ; Mg: real;
BEGIN
Assign (F, ‘ Studenţi.txt’);
Append(F);
Write(‘ Nume student: ’); Readln(Nume);
Write(‘ Prenume student: ’); Readln(Prenume);
Write(‘ Media : ’); Readln(Mg);
Writeln(F, Nume ,’ ‘, Prenume ,’ ‘, Mg:5:2);
Close(F);
END;

4. Extragerea unor date de tipuri diferite. Verificarea existentei unui fisier.


procedure ExtragereDate(NumeF:String);
Var
F:Text;
Ch:Char;
Nm,Pr:String[20];
Medie:Real;
begin
{$I-}
Assign(F,NumeF);
Reset(f);
{$I+}
if ioresult<>0 then
begin
WriteLn('Eroare nu exista fisierul:');
Halt;
end;
while not eof(f) do
begin
Nm:='';
repeat
Read(F,Ch);
if Ch<> ' ' then
Nm:=Nm+Ch;
until Ch=' ';
Pr:='';
repeat
Read(F,Ch);
if Ch<> ' ' then
Pr:=Pr+Ch;
until Ch=' ';
Readln(F,Medie);
10 Curs 1 - STRUCTURU DE DATE

WriteLn(Nume,' ',Prenume,' ', Medie:5:2);


end;
Close(f);
end;

Exemple de prelucrare a fişierelor cu tip.

Operaţiile de prelucrare:
a. Crearea fişierului cu tip :
Ex: Creaţi un fişier cu tip ce păstrează informaţiile despre studenţi (Nume, Pren, Mg).
TYPE Student = Record
Nume, Pren : string[20];
Mg: real;
END;

PROCEDURE Creare;
VAR F: FILE OF Student;
S: Student;
Răsp : string[2];
BEGIN
Assign (F, ‘ Studenţi.dat’);
Rewrite(F);
Repeat
Write(‘ Nume student: ’);Readln(S.Nume);
Write(‘ Prenume student: ’);Readln(S.Pren);
Write(‘ Media : ’); Readln(S.Mg);
Write (F,S);
Write(‘Mai aveti studenţi (DA / NU) ? ‘);
Readln(Răsp);
Until Răsp = ‘NU’;
Close(F);
END;

b. Afişarea fişierului cu tip:

PROCEDURE Afişare;
VAR F: FILE OF Student;
S: Student;
BEGIN
Assign (F, ‘ Studenţi.dat’);
Reset(F);
While not EOF (F) do
Begin
Read(F, S);
Writeln(S.Nume,’ ‘,S.Pren,’ ‘,S.Mg);
End;
Close(F);
END;

c. Căutarea datelor( trebuie să ştim ce tip de date sunt în fişier):

PROCEDURE Căutare;
VAR F: FILE OF Student;
S: Student;
Nm,Pr : string[20]; Găsit : boolean;
BEGIN
Assign (F, ‘ Studenţi.dat’);
Reset(F);
STRUCTURI DE DATE - Curs 2 11

Write (‘ Numele studentului care se caută : ’); Readln(Nm);


Write (‘ Prenumele studentului care se caută : ’); Readln(Pr);
Găsit := False;
While not EOF (F) do
Begin
Read(F, S);
IF (S.Nume=Nm) AND (S.Pren=Pr) THEN
Begin
Găsit := True;
Writeln(‘Există studentul ‘,S.Nume,’ ‘,S.Pren,’ ‘, S.Mg);
End;
End;
IF not Găsit THEN
Writeln (‘ Nu există studentul cu acest nume ‘);
Close(F);
END;

a. Ştergerea unei înregistrări


- trebuie identificată înregistrarea care va fi ştearsă;
- vrem să ştergem înregistrarea Si

S1 S2 … Si … Sn

- vom folosi un fişier temporar Temp ;

S1 S2 …Si-1 Si+1 … Sn

PROCEDURE Stergere;
VAR F,G: FILE OF Student;
S: Student;
Nm,Pr : string[20];
BEGIN
Assign (F, ‘ Studenţi.dat’);
Reset(F);
Assign (G,‘ Temp.dat’);
Rewrite(G);
Write (‘ Numele studentului de şters : ’);
Readln(Nm);
Write (‘ Prenumele studentului de şters : ’);
Readln(Pr);

While not EOF (F) do


Begin
Read(F, S);
IF (S.Nume<>Nm) OR ((S.Nume=Nm) AND (S.Pren<>Pr)) THEN
Write (G,S);
End;
Close(F);
Close(G);
Erase(F);
Rename(G,’Studenţi.dat’);
END;

e. Modificarea unei înregistrări:

Varianta 1. Folosind un fisier temporar.


PROCEDURE Modificare;
12 Curs 1 - STRUCTURU DE DATE

VAR F,G: FILE OF Student;


S: Student;
Nm,Pr : string[20];
BEGIN
Assign (F, ‘ Studenţi.dat’);
Reset(F);
Assign (G,‘ Temp.dat’);
Rewrite(G);
Write (‘ Numele studentului de modificat : ’);
Readln(Nm);
Write (‘ Prenumele studentului de modificat: ’);
Readln(Pr);
While not EOF (F) do
Begin
Read(F, S);
IF (S.Nume=Nm) AND (S.Pren=Pr) THEN
Begin
Write(‘ Noul nume: ‘); Readln(S.Nume);
Write(‘Noul prenume : ‘); Readln(S.Pren);
Write(‘ Noua medie : ‘); Readln(S.Mg);
End;
Write (G,S);
End;
Close(F);
Close(G);
Erase(F);
Rename(G,’Studenţi.dat’);
END;

Varianta 2. Prin pozitionare explicita in fisier.


type elev=record
nume,prenume:string[20];
varsta :byte;
medie:real;
end;

procedure Modificare;
var F:file of elev;
e:elev;
Nm,Pn:String[20];
begin
Write('Dati numele elevului pentru care se modifica datele:');
ReadLn(Nm);
Write('Dati prenumele elevului pentru care se modifica datele:');
ReadLn(Pn);
Assign(f,'elevi.dat');
Reset(f);
repeat
Read(f,E);
if (Nm=E.Nume) and (E.Prenume=Pn) then
begin
WRite('Dati noua varsta : ');ReadLN(E.Varsta);
WRite('Dati noua medie : ');ReadLN(E.Medie);
Seek(f,filepos(f)-1);
Write(f,E);
end;
until eof(f);
Close(f);
end;
STRUCTURI DE DATE - Curs 2 13

e. Ordonarea fizica a unui fisier.


procedure Ordonare;
Var F:file of elev;
E,E1:Elev;
k:Boolean;
begin
Assign(f,'elevi.dat');
Reset(f);
repeat
k:=false;
Read(f,E);
repeat
Read(f,E1);
if (E.Nume>E1.Nume) or (E.nume=E1.Nume) and (E.Prenume>E1.prenume) then
begin
Seek(f,filepos(f)-2);
Write(f,E1);
Write(f,E);
k:=true;
end
else
E:=E1;
until eof(f);
Seek(f,0);
until k=false;
end;

Exemple de prelucrare a fişierelor fara tip.

1. Se doreşte evidenţa datelor despre studenţii unei facultăţi. Pentru aceasta se construieşte un fişier fără
tip care conţine următoarele date:
- la începutul fişierului un antet cu nume facultate, nr grupe şi lista cu numele grupelor din
facultate si nr de studenti din fiecare grupa.
- Pentru fiecare grupa înregistrări cu datele studentilor din aceea grupa astfel: nume, prenume,
grupa, medie generala, grupa..
Program FisiereFaraTip;
Type
AntetFacultate=Record
NumeFac:String[100];
NrGrupe:Byte;
Den:array[1..200] of String[20];
NrSt:array[1..200] of Byte;
end;
AntetStudent=Record
Nume,Pren:String[30];
Grupa:String[20];
Medie:Real;
end;

Procedure CreareFisier;
Var F: File;
BFac:AntetFacultate;
14 Curs 1 - STRUCTURU DE DATE

BStud:AntetStudent;
I:Byte;
R:String[1];
begin
Assign(F,'facult.dat');
Rewrite(F,1);
Write('Nume facultate :');
ReadLn(BFac.NumeFac);
Write('Numar grupe :');
ReadLn(BFac.NrGrupe);
for i:=1 to BFac.NrGrupe do
begin
Write('Nume grupa ',I,':');
ReadLn(BFac.Den[I]);
Write('Numar studenti grupa ',I,':');
ReadLn(BFac.NrSt[I]);
end;
BlockWrite(F,Bfac,SizeOF(BFac));
repeat
Write('Nume student ');
ReadLn(BStud.Nume);
Write('Prenume student ');
ReadLn(BStud.Nume);
Write('Grupa studentului ');
ReadLn(BStud.Grupa);
Write('Media studentului ');
ReadLn(BStud.Medie);
Write('Mai adaugati studenti ');
ReadLn(R);
BlockWrite(F,BStud,SizeOF(BStud));
until (R='N') or (R='n');
Close(F);
end;

Procedure AfisareFisier;
Var F: File;
BFac:AntetFacultate;
BStud:AntetStudent;
I:Byte;
R:String[1];
begin
Assign(F,'facult.dat');
Reset(F,1);
BlockRead(F,Bfac,SizeOF(BFac));
WriteLn('Nume facultate :',BFac.NumeFac);
WriteLn('Numar grupe :',BFac.NrGrupe);
for i:=1 to BFac.NrGrupe do
WriteLn('Nume grupa ',I,':', BFac.Den[I],' ' , BFac.NrSt[I]);
while Not Eof(F) do
begin
BlockRead(F,BStud,SizeOF(BStud));
WriteLn(BStud.Nume,' ',BStud.Nume,' ',BStud.Grupa,'
',BStud.Medie);
end;
Close(F);
end;

begin
CreareFisier;
STRUCTURI DE DATE - Curs 2 15

AfisareFisier;
ReadLn;
end.

2. Să considerăm un fisier de tip imagine BMP. Se doreste prelucrarea acestuia: afisarea pe ecran si
salvarea continutului ecranului intr-un fisier imagine de tip BMP.

unit Bitmap; (* Salvarea si afisarea imaginilor BMP ce au 16 culori *)

interface

uses Crt,graph;

type
BitMapFileHeader = record
BfType : Word ; { tipul fisierului }
BfSize : LongInt ; { marimea fisierului }
BfReser1 : Word ;
BfReser2 : Word ;
BfOffBits : LongInt ; { adresa relativa in fisier a codificarii imaginii }
end;

BitMapInfoHeader = record
BSize : LongInt ;{ numarul de octeti din structura }
BWidth : LongInt ; { latimea imaginii in pixeli }
BHeight : LongInt ; { inaltimea imaginii in pixeli }
BPlanes : Word ;
BCount : Word ; { numarul de biti /pixel :1, 4, 8 sau 24 }
BCompression : LongInt ;{ modul de compresie ( 0 daca nu este comprimata imaginea ) }
BSizeImag : LongInt ;{ numarul de octeti ocupati de reprezentarea imaginii }
BResOriz : LongInt ;{ rezolutia pe orizontala ,in pixeli pe metru }
BResVert : LongInt ;{ rezolutia pe verticala ,in pixeli pe metru }
BColorNumb : LongInt ; { numarul de culori utilizate in imagine }
BColorNumbImport : LongInt; { numarul de culori importante }
end;

BitMapRGB = record
rgbBlue : Byte ;
rgbGreen : Byte ;
rgbRed : Byte ;
rgbReserv : Byte ;
end;

const
ColorReg: array[0..15] of Byte = ( 0, 1, 2, 3, 4, 5, 20, 7,
56, 57, 58, 59, 60, 61, 62, 63);
mask:array[0..7] of byte=(128,64,32,16,8,4,2,1);

var

TabColor : array [0..15] of BitMapRGB ;


BufFileHeader : BitMapFileHeader ;
BufInfoHeader : BitMapInfoHeader ;
Gd,Gm,X,Y: Integer;
Rc,Gc,Bc,C:Byte;
Register : Byte;
16 Curs 1 - STRUCTURU DE DATE

BFile : array [1..30004] of byte;

Procedure LoadBmpImag (name : String; X, Y : Integer);


Procedure SaveBmpImag (name : String; X1,Y1,X2,Y2 : Integer);

Implementation

Procedure SetRGBPal ;
var
I : Integer;
begin
for I:=0 to 15 do
SetRGBPalette(ColorReg[I],TabColor[I].rgbRed SHR 2,TabColor[I].rgbGreen shr
2,TabColor[I].rgbBlue SHR 2);
end;

procedure GetPaletteReg; assembler;


asm
mov dx, $03c7
mov al, Register
out dx, al
mov dx, $03c9
in al, dx
mov RC, al
in al, dx
mov GC, al
in al, dx
mov BC, al
end;

Procedure LoadBmpImag (name : String; X, Y : Integer);


var
Fbmp : File;
NumbB,NumbB1,NumbRead,K,I,Cul,n,Z : Integer;

begin
Assign(Fbmp,name);
{$I-}
Reset(Fbmp,1);
{$I+}
if ioresult<>0 then
begin
sound(440);
delay(200);
nosound;
end;
BlockRead( Fbmp, BufFileHeader,sizeof(BitMapFileHeader));
BlockRead( Fbmp, BufInfoHeader,sizeof(BitMapInfoHeader));
if (BufInfoHeader.BCount >0) and (BufInfoHeader.BColorNumb =0) then
begin
n :=1;
n :=n SHL BufInfoHeader.BCount;
BlockRead(Fbmp, TabColor,n*sizeof(BitMapRGB));
SetRGBPal;
end;
K := 8 div BufInfoHeader.BCount;
NumbB := BufInfoHeader.BWidth div K;
NumbB1 := NumbB;
if NumbB mod 4 <>0 then NumbB1:=NumbB div 4 *4+4;
STRUCTURI DE DATE - Curs 2 17

Z:=X;
Y := Y + BufInfoHeader.BHeight;
repeat
BlockRead(Fbmp,BFile,NumbB1,NumBRead);
for I :=1 to NumbB do
begin
Cul:=BFile[I] SHR 4;
PutPixel(X,Y,Cul);
Inc(X);
Cul:=(BFile[I] SHL 4) SHR 4 ;
PutPixel(X,Y,Cul);
Inc(X);
end;
X:=Z;
Dec(Y);
until NumbRead=0 ;
close(Fbmp);
end;

Procedure SaveBmpImag (name : String; X1,Y1,X2,Y2 : Integer);


var
Fbmp : File;
NumbB,NumbB1,NumbRead,K,I,Cul,n,Z,R: Integer;
B:Byte;
begin
Assign(Fbmp,name);
Rewrite(Fbmp,1);
BufFileHeader.BfType := 19778 ; { tipul fisierului }
BufFileHeader.BfSize :=118+(x2-x1)*(y2-y1) div 2; ; { marimea fisierului }
BufFileHeader.BfReser1 :=0 ;
BufFileHeader.BfReser2 :=0 ;
BufFileHeader.BfOffBits := 118; { adresa relativa in fisier }
BlockWrite( Fbmp, BufFileHeader,sizeof(BitMapFileHeader));
BufInfoHeader.BSize := 40 ;{ numarul de octeti din structura }
BufInfoHeader.BWidth := X2-X1+1 ; { latimea imaginii in pixeli }
BufInfoHeader.BHeight := Y2-Y1+1 ; { inaltimea imaginii in pixeli }
BufInfoHeader.BPlanes := 1 ;
BufInfoHeader.BCount := 4 ; { numarul de biti /pixel :1, 4, 8 sau 24 }
BufInfoHeader.BCompression := 0 ;{ modul de compresie ( 0 daca nu este comprimata imaginea ) }
BufInfoHeader.BSizeImag := (X2-X1)*(Y2-Y1) div 2; ;{ numarul de octeti ocupati de reprezentarea
imaginii }
BufInfoHeader.BResOriz := 0 ;{ rezolutia pe orizontala ,in pixeli pe metru }
BufInfoHeader.BResVert := 0 ;{ rezolutia pe verticala ,in pixeli pe metru }
BufInfoHeader.BColorNumb := 0; { numarul de culori utilizate in imagine }
BufInfoHeader.BColorNumbImport := 16 ;
BlockWrite( Fbmp, BufInfoHeader,sizeof(BitMapInfoHeader));
for I:=0 to 15 do
begin
Register := ColorReg[I];
GetPaletteReg;
TabColor[I].rgbBlue := Bc SHL 2;
TabColor[I].rgbGreen := Gc SHL 2;
TabColor[I].rgbRed := RC SHL 2;
TabColor[I].rgbReserv := 0;

end;
BlockWrite(Fbmp,TabColor,16*sizeof(BitMapRGB));
K:=0;
for Y:=Y2 downto Y1 do
18 Curs 1 - STRUCTURU DE DATE

begin
X:=X1;
for I:=1 to (X2 -X1) div 2+1 do begin
B := (Getpixel(X,Y) SHL 4) or (GetPixel(X+1,Y));
Inc(K);
BFile[K] := B;
if K>30000 then
begin
BlockWrite(Fbmp,BFile,K);
K:=0;
end;
Inc(X,2);
end;
if ((X2 -X1) div 2+1 )Mod 4 <>0 then
begin
R:=((X2 -X1) div 2+1) mod 4 ;
K := K +4-R;
end;

if K>30000 then
begin
BlockWrite(Fbmp,BFile,K);
K:=0;
end;
end;
BlockWrite(Fbmp,BFile,K);
Close(Fbmp);
end;
end.

Aplicatii laborator2:
1. (fişiere text).
Se consideră fişierul text candidati.txt, conţinând pe fiecare linie datele candidaţilor la un concurs de
admitere : numele, prenumele, notele la cele trei probe de concurs şi media generală. Se cere un program
de prelucrare care să permită:
a. adăugarea de noi candidati.
b. Ştergerea unui candidat cunoscându-i numele.
c. Afişarea candidaţilor în ordinea descrescătoare a mediei generale.
d. Afişarea candidaţilor ce au avut note de 10 la probele de concurs (afişând studenţi care
au obţinut aceste rezultate).
e. Crearea unui alt fişier cu candidaţii ce au obţinut la fiecare probă peste 5. Fişierul va
conţine candidaţii sub forma unui tabel.
2. Fişiere fără tip, combinate cu fişiere text.
Se doreşte evidenţa datelor despre studenţii unei facultăţi. Pentru aceasta se construieşte un fişier fără tip
care conţine următoarele date:
- la începutul fişierului un antet cu nume facultate, nr grupe şi lista cu numele grupelor din
facultate si nr de studenti din fiecare grupa.
STRUCTURI DE DATE - Curs 2 19

- Pentru fiecare grupa înregistrări cu datele studentilor din aceea grupa astfel: nume, prenume,
grupa, medie generala.
Se cere crearea unui astfel de fisier fara tip, introducerea datelor despre studentii facultatii. De asemenea,
se vor afisa grupele ordonate alfabetic şi se va determina pentru fiecare grupa care a fost media grupei.
Pentru un nume si prenume de student preluat de la tastatura se va verifica daca exista in baza de date
creata, in caz afirmativ afisandu-se datele pe ecran. Pentru un nume de grupa tastat se va crea un fisier
text cu studentii acelei grupe.

3. Tema pentru acasa.


La un concurs de admitere s-au înscris mai mulţi candidaţi. La înscriere s-au reţinut, pentru fiecare
candidat, următoarele date : nume, prenume, iniţiala tatălui, data naşterii. Se cere realizarea unui program
ce permite evidenţa admiterii cu ajutorul computerului. În acest scop, programul va permite :
- citirea datelor despre candidaţi la înscriere şi stocarea lor într-un fişier binar.
- împărţirea candidaţilor pe săli, ştiind că există suficiente săli şi că în fiecare sală pot intra
maxim m candidaţi.
- introducerea şi stocarea notelor la cele trei probe de concurs împreună cu determinarea medie
generale a fiecărui candidat.
- crearea unui fişier text, numit admisi.txt, conţinând lista cu candidaţii admişi. Un candidat a fost
admis dacă a obţinut note peste 5 (inclusiv) la fiecare din cele trei probe.
- crearea unui fişier text, numit respinsi.txt, conţinând lista cu candidaţii respinsi. Un candidat a
fost respins dacă a obţinut cel puţin o notă sub 5 la una din cele trei probe.
să se afişeze o statistică privind ponderea celor admişi faşă de cei respinşi

S-ar putea să vă placă și