Sunteți pe pagina 1din 19

Algoritmi şi programe de prelucrare a fişierelor

4. ALGORITMI DE PRELUCRARE A FIŞIERELOR SECVENŢIALE

Din punct de vedere al operaţiilor de gestiune solicitate de diverse aplicaţii, fişierele binare
se pot grupa în fişiere care nu sunt actualizate (ţinute la zi) şi fişiere care sunt actualizate. De obicei,
fişierele din prima grupă se regăsesc în aplicaţii matematice sau ca fişiere temporare şi de tranzacţii
în aplicaţii de gestiune economică. Fişierele din cea de-a doua grupă sunt, de obicei, fişiere perma-
nente (principale) în aplicaţii de gestiune economică şi au particularităţi de proiectare, referitoare, în
special, la asigurarea ştergerii şi adăugării de articole.
Asupra fişierelor binare care nu necesită actualizare se realizează, de obicei, operaţiile de
creare (populare) şi consultare. Dintre operaţiile de actualizare pot fi realizate, fără mari complicaţii,
modificarea şi adăugarea densă de articole.

♦ Popularea fişierelor se realizează prin preluarea datelor fie din alte fişiere, fie de la tastatură
(popularea interactivă). În ultimul caz, cel mai des întâlnit în practică, fişierul conducător corespunde
mulţimii datelor introduse de la tastatură. Articolele sunt preluate câmp cu câmp, neexistând
posibilitatea citirii unei variabile de tip articol şi, în plus, introducerea unei date este adesea însoţită de
proceduri de validare specifice, cu reintroducerea ei în cazul unei erori.
Sfârşitul introducerii datelor de la tastatură (şi implicit a procesului de populare a fişierului)
poate fi:
- De tip chestionar, prin consultarea utilizatorului, privind continuarea sau nu a introducerii
articolelor. Pentru un volum mare de date, varianta prezintă dezavantajul măririi timpului de
prelucrare.
- Convenţional, prin introducerea pentru primul câmp din articol a unei valori prestabilite, cu
semnificaţie de sfârşit de prelucrare.
- Standard, prin tastarea caracterului CTRL-Z, cu rol de sfârşit de fişier TEXT, caz în care
variabilei standard CheckEof (definită în unitatea standard CRT) trebuie să i se atribuie în program
valoarea TRUE.
Schema logică a algoritmului de prelucrare este similară celor prezentate în capitolul 1, cu
următoarele particularităţi:
- modulul ÎNCEPUT are ca ultimă operaţie, fie afişarea numelui primului câmp din articol, fie
poziţionarea pe zona de pe ecran de unde se va prelua valoarea primului câmp (în cazul formatării
ecranului);
- modulul PRELUCRARE începe cu citirea primului câmp, urmată de citirea celorlalte
câmpuri (eventual cu validările stabilite) şi se termină cu afişarea numelui primului câmp sau cu
poziţionarea pe zona ecran de unde va fi preluată valoarea acestuia (similar operaţiei din modulul
ÎNCEPUT).
O altă problemă a populării fişierelor binare o reprezintă aşezarea articolelor pe suportul extern.
Din acest punct de vedere se întâlnesc două modalităţi:
• Populare densă, prin care articolele se scriu unul după altul, în ordinea în care au fost
furnizate, fără a se lăsa locuri libere (acces secvenţial). Pentru fişierele care nu necesită actualizare
acesta este tipul recomandat.
• Populare aleatoare, prin care articolele sunt scrise pe poziţiile al căror număr relativ este
furnizat explicit de programator (acces direct). Scrierea unui articol se realizează după poziţionarea pe
numărul relativ dorit, cu procedura Seek(f,nr_relativ). La populare, nr_relativ nu este limitat decât de
spaţiul existent pe suportul extern.
Metoda are dezavantajul că necesită evidenţa "articolelor vide". În cazul fişierelor care nu
necesită actualizare, popularea aleatoare se recomandă numai dacă, după creare, fişierul este dens.

Exerciţiul 1: Să se realizeze programul pentru crearea unui fişier secvenţial Facturi.dat, care
memorează datele referitoare la facturile emise de către o societate comercială, într-un anumit an.
Structura articolului este următoarea:
Algoritmi şi programe de prelucrare a fişierelor
Număr Data emiterii Denumire Cod fiscal Valoare TVA
factură Lună Zi beneficiar facturată facturat
String[10] 1..12 1..31 String[20] Longint Real Real

Datele se introduc de la tastatură, câmp cu câmp, fără validare. Sfârşitul introducerii este
standard (se tastează <CTRL/Z> în câmpul nr_fact). Programul de creare a fişierului Facturi.dat
este Creare.

Program Creare;
Uses crt;
Type
data = record
luna:1..12;
zi:1..31
end;
art_fact = record
nr_fact:string[10];
data_emit:data;
den_benef:string[20];
cod_fiscal:longint;
valoare,tva:real
end;
Var
f:file of art_fact;
factura:art_fact;
Begin
Assign(f,'facturi.dat'); Rewrite(f);
checkeof:=true; clrscr;
With factura do begin
Gotoxy(15,10); Write('Nr. factura: '); Gotoxy(40,10);
While not eof do
begin
Readln(nr_fact);
Gotoxy(15,11); Writeln('Data emiterii');
Gotoxy(22,12); Writeln('luna:');
Gotoxy(40,12); Readln(data_emit.luna);
Gotoxy(22,13); Writeln('ziua:');
Gotoxy(40,13); Readln(data_emit.zi);
Gotoxy(15,14);Writeln('Denumire benef.:');
Gotoxy(40,14); Readln(den_benef);
Gotoxy(15,15); Writeln('Cod fiscal:');
Gotoxy(40,15); Readln(cod_fiscal);
Gotoxy(15,16); Writeln('Valoare facturata:');
Gotoxy(40,16); Readln(valoare);
Gotoxy(15,17); Writeln('TVA facturat:');
Gotoxy(40,17); Readln(tva);
Write(f,factura);
clrscr;
Gotoxy(15,9); Write('Nr. factura: ');
Gotoxy(40,9)
End;
Close(f)
Algoritmi şi programe de prelucrare a fişierelor
End
End.

♦ Consultarea fişierelor are mai multe variante, în funcţie de scopul prelucrării. După modul
de regăsire a articolelor în cadrul fişierului consultarea poate fi secvenţială, directă sau mixtă.
• Consultarea secvenţială presupune regăsirea articolelor în ordinea în care sunt memorate pe
suportul extern. După numărul articolelor prelucrate, consultarea secvenţială poate fi: integrală, când
se prelucrează toate articolele fişierului; cu selecţie, când se prelucrează numai acele articole care au
una sau mai multe caracteristici comune. După numărul de caracteristici, selecţia poate fi simplă,
dublă, multiplă. Pentru consultarea secvenţială se poate utiliza oricare din tipurile de algoritmi prezen-
taţi în figurile 1.2 - 1.6.

Exemplu: Obţinerea unei situaţii cu mai multe grade de total.


Pentru aceasta se stabilesc câmpuri, numite caracteristici de grupare sau caracteristici de
control, asociate gradelor de total. O caracteristică de control este un câmp al articolului din fişierul de
date, care are aceeaşi valoare pentru mai multe înregistrări. Astfel, articolele care au valoare comună
pentru o caracteristică de grupare se pot ordona pe submulţimi, formând o grupă de control.
Fişierul poate constitui, în ansamblul său, caracteristica de grupare de cel mai înalt nivel, pentru
care se poate calcula totalul general. Numărul maxim de grade de total este superior cu unu numărului
de caracteristici de control stabilite.
Între caracteristicile de grupare se stabileşte o relaţie de ordine ierarhică. Pentru prelucrarea
fişierului, cu utilizare minimă de memorie, articolele trebuie sortate după caracteristicile de control.
Acest tip de prelucrare intră în categoria consultărilor secvenţiale integrale şi urmează algoritmul de
principiu din figurile 1.3 sau 1.4. Prelucrarea unui fişier sortat după criteriile enunţate, presupune
existenţa unor operaţii standard, executate la schimbarea valorii fiecărei caracteristici de control
stabilite:
• operaţii iniţiale ale unei grupe de control prin care se iniţializează variabila de total specifică
grupei; se salvează valoarea caracteristicii primului articol din grupă; alte operaţii iniţiale specifice
grupei;
• operaţii finale ale unei grupe de control prin care se afişează totalul calculat pentru
caracteristica ce se schimbă; se cumulează totalul grupei curente la totalul grupei ierarhic superioară;
alte operaţii finale specifice grupei;
• condiţia de prelucrare a unei grupe de control conţine, pe lângă condiţia specifică, toate
celelalte condiţii din amonte.
Raportul final este listat la imprimantă, fie direct, ca fişier de ieşire, fie creat pe suport
magnetic, ca fişier TEXT, în vederea imprimării ulterioare. Structura unei pagini a raportului şi
controlul trecerii la o nouă pagină trebuie asigurate de programator.
În continuare se prezintă structura de principiu a unui program de obţinere a unui raport final,
cu control după două caracteristici şi trei grade de total, unde câmp_1 şi câmp_2 sunt caracteristicile
de control (câmpuri din articol), v1 şi v2 sunt variabile de lucru pentru salvarea caracteristicilor, iar
totg, tot1 şi tot2 sunt variabile pentru calculul gradelor de total. Analog, se poate extinde pentru
oricâte caracteristici şi grade de total.
..............................................................
procedure inceput;
begin
(* citire nume fisiere externe *)
assign(f,nume_fisier); reset(f);
assign(g,lista); rewrite(g);
sf:=false; totg:=0;
(* -------------------------------------
scriere in lista a antetului si a capului de tabel
-------------------------------------- *)
Algoritmi şi programe de prelucrare a fişierelor
read(f,x);
end;
procedure inceput_1;
begin
tot1:=0; v1:=x.camp_1;
end;
procedure inceput_2;
begin
tot2:=0; v2:=x.camp_2;
end;
procedure sfarsit_1;
begin
writeln('total 1 = ',tot1);
totg:=totg+tot1
end;
procedure sfarsit_2;
begin
writeln('total 2 = ',tot2);
tot1:=tot1+tot2
end;
procedure sfarsit;
begin
writeln('total general = ',totg);
close(f); close(g)
end;
procedure prel_art_x;
begin
(* -----------------------------
prelucrarea articolului x
----------------------------- *)
if eof(f) then sf:=true else read(f,x)
end;
procedure prel_2;
begin
inceput_2;
while (v1=x.camp_1) and (v2=x.camp_2) and not sf
do prel_art_x;
sfarsit_2;
end;
procedure prel_1;
begin
inceput_1;
while (v1=x.camp_1) and not sf do prel_2;
sfarsit_1;
end;
begin
inceput;
while not sf do prel_1;
sfarsit;
end.
Algoritmi şi programe de prelucrare a fişierelor
Exerciţiul 2: Să se realizeze programul pentru obţinerea unei liste cu valoarea lunară facturată şi
TVA-ul aferent, pentru fiecare beneficiar către care au fost emise facturi, utilizând informaţiile
memorate în fişierul creat prin programul prezentat în exerciţiul 1. Numărul şi denumirile
beneficiarilor sunt necunoscute la momentul proiectării. Schema de sistem este prezentată în figura
3.1.
Programul Consultare este structurat pe trei module:
• modulul Creare_manevra (1) copiază într-un fişier intermediar (fişier de manevră)
informaţiile utile obţinerii situaţiei de ieşire, în vederea sortării lor;
• modulul Sortare_manevra (2) realizeză sortarea fişierului de manevră prin metoda
selecţiei, după valoarea câmpului den_benef;
• modulul Listare (3) realizează obţinerea situaţiei finale într-un fişier magnetic de tip
TEXT.

CONSULTARE
Facturi.dat Tabel.txt
1 2 3

Manevra.tmp

Fig. 3.1. Schema de sistem a programului de consultare

Program Consultare;
Uses crt;
Type data = record
luna:1..12;
zi:1..31
end;
art_fact = record
nr_fact:string[10];
data_emit:data;
den_benef:string[20];
cod_fiscal:longint;
valoare,tva:real
end;
art_man = record
data_emit:data;
den_benef:string[20];
valoare,tva:real
end;
Var f:file of art_fact;
factura:art_fact;
manevra:file of art_man;
aux:art_man;
lista:text;
{**************************************************}
Procedure Creare_manevra;
Begin
Assign(f,'facturi.dat'); Reset(f);
Assign(manevra,'manevra.tmp'); Rewrite(manevra);
Algoritmi şi programe de prelucrare a fişierelor
While not eof(f) do
begin
Read(f,factura);
aux.data_emit:=factura.data_emit;
aux.den_benef:=factura.den_benef;
aux.valoare:=factura.valoare;
aux.tva:=factura.tva;
Write(manevra,aux)
end;
Close(f);
Close(manevra)
End;
{**************************************************}
Procedure Sortare_manevra;
Var
art1,art2:art_man;
i,j:word;
Begin
Assign(manevra,'manevra.tmp'); Reset(manevra);
For i:=1 to filesize(manevra)-1 do
Begin
Seek(manevra,i-1); Read(manevra,art1);
For j:=i+1 to filesize(manevra) do
Begin
Seek(manevra,j-1); Read(manevra,art2);
If art1.den_benef > art2.den_benef then
Begin
Seek(manevra,i-1); Write(manevra,art2);
Seek(manevra,j-1); Write(manevra,art1);
art1:=art2
End
End
End;
Close(manevra)
End;
{**************************************************}
Procedure Listare;
Var
sf:boolean; i:1..12;
c:string[20];
tot_val,tot_tva:array[1..12] of real;
Const
luni:array[1..12] of string[3]=
('Ian','Feb','Mar','Apr','Mai','Iun','Iul','Aug','Sep','Oct','Nov','Dec');
Begin
Assign(manevra,'manevra.tmp'); Reset(manevra);
Assign(lista,'tabel.txt'); Rewrite(lista);
sf:=false;
Writeln(lista,'Tabel cu valorile facturate lunar, pe beneficiari');
Writeln(lista);
Writeln(lista,’Valoare TVA’);
With aux do begin
Algoritmi şi programe de prelucrare a fişierelor
Read(manevra,aux);
While not sf do
begin
c:=den_benef;
for i:=1 to 12 do begin tot_val[i]:=0; tot_tva[i]:=0 end;
While (c=den_benef) and not sf do
begin
tot_val[data_emit.luna]:= tot_val[data_emit.luna]+valoare;
tot_tva[data_emit.luna]:= tot_tva[data_emit.luna]+tva;
{$I-} Read(manevra,aux); {$I+}
If IOresult <> 0 then sf:=true
end;
Writeln(lista,c);
for i:=1 to 12 do
Writeln(lista,' ':5,luni[i],':',tot_val[i]:12:0,tot_tva[i]:10:0)
end;
Close(manevra);
Erase(manevra);
Close(lista)
end
End;

{**************************************************}
{programul principal}

Begin
Creare_manevra;
Sortare_manevra;
Listare
End.

• Consultarea în acces direct presupune regăsirea articolului după numărul relativ, prin
secvenţa Seek(f,nr_relativ); Read(f,art). Numărul relativ este furnizat de utilizator şi trebuie să
aparţină domeniului 0..FileSize(f)-1. Se remarcă faptul că dacă nr_relativ depăşeşte dimensiunea
fişierului, procedura Seek nu generează eroare, dar citirea va determina întreruperea execuţiei
programului. Pentru evitarea acestei situaţii se va include în program validarea apartenenţei numărului
relativ la intervalul acceptat. Algoritmul de consultare în acces direct a unui fişier are un alt fişier
conducător (de exemplu, tastatura).

Exemplu:
............................
begin
(* citire nume fisier extern *)
checkeof:=true; assign(f,nume_fisier); reset(f);
write('nr. relativ: ');
while not eof do
begin
readln(r); {citirea numarului relativ al articolului}
seek(f,r); {$i-} read(f,art); {$i+}
if ioresult = 0 then
(* ------------------------
prelucrare articol
Algoritmi şi programe de prelucrare a fişierelor
------------------------ *)
else
writeln('Articol inexistent !');
write('Nr. relativ (sau ctrl-z): ')
end;
close(f)
end.

• Consultarea în acces mixt utilizează o combinaţie între accesul direct şi cel secvenţial, în
vederea prelucrării unui grup de articole, memorate contiguu în fişier şi selectabile printr-o condiţie.
Pentru fişierele binare, metoda poate fi aplicată dacă se doreşte selectarea articolelor dintre două limite
ale numerelor relative (limita inferioară - li şi limita superioară - ls). Algoritmul trebuie să verifice
relaţia 0≤≤li≤ls<FileSize(f), după care parcurgerea fişierului poate fi realizată prin orice tip de structură
repetitivă.

Exemplu:
............................
begin
(* citire nume fisier extern *)
assign(f,nume_fisier);
reset(f);
write('limita inferioara: ');
readln(li); { citirea nr. relativ al primului articol din secventa }
write('limita superioara: ');
readln(ls); { citirea nr. relativ al ultimului articol din secventa }
if (0<=li) and (li<=ls) and (ls<filesize(f)) then
begin
seek(f,li);
for i:=li to ls do
begin
read(f,art);
(* -----------------------
prelucrare articol
----------------------- *)
end
end
else
writeln('>> Nu este indeplinita conditia de limite');
close(f)
end.

♦ Adăugarea de articole se realizează, în general, cu tranzacţii de la terminal, similar operaţiei


de populare. Pentru o corectă exploatare ulterioară, adăugarea trebuie să fie densă. Acest lucru poate fi
realizat astfel:
• Adăugare la sfârşit (extindere), după ultimul articol scris. Operaţia se realizează similar
populării în acces secvenţial, după poziţionarea pe marcatorul de sfârşit de fişier, cu procedura
Seek(f,FileSize(f)).

Exemplu:
..................
begin
(* citire nume fisier extern *)
Algoritmi şi programe de prelucrare a fişierelor
assign(f,nume_fisier);
reset(f);
seek(f,filesize(f)); { pozitionare dupa ultimul articol scris }
checkeof:=true;
write('camp 1: ');
while not eof do
begin
readln(art.camp_1);
(* -----------------------------------------------
preluare de la tastatura a celorlalte
campuri din articol
------------------------------------------------ *)
write(f,art);
write('camp 1 (sau ctrl-z): ')
end;
close(f)
end.

• Inserarea unor articole. Se aplică în cazul în care articolele sunt scrise în fişier în ordinea
crescătoare (descrescătoare) a valorilor unui anumit câmp. În acest caz, noul articol va fi inserat între
două articole, astfel:
- se caută (cu un algoritm secvenţial, binar etc.) poziţia k în care trebuie inserat noul articol;
- se copiază, glisând cu o poziţie spre dreapta, toate articolele de la sfârşitul fişierului până la
articolul cu numărul relativ k;
- se scrie în acces direct noul articol, în poziţia k.

Exemplu:
{ articolele fisierului sunt in ordinea crescatoare a valorii campului 1 }
begin
(* citire nume fisier extern *)
assign(f,nume_fisier);
reset(f);
checkeof:=true;
write('camp 1: ');
while not eof do { se asigura adaugarea mai multor articole }
begin
readln(art_nou.camp_1); { introducerea campului
dupa care sunt sortate articolele }
(* -----------------------------------
preluare de la tastatura a celorlalte
campuri din articolul de adaugat
----------------------------------- *)
{ secventa de cautare a pozitiei in care se va insera articolul }
seek(f,0); { pozitionare pe inceput de fisier }
sf:=false;
read(f,art_existent);
while not sf and (art_existent.camp_1<art_nou.camp_1) do
begin
read(f,art_existent);
if ioresult <> 0 then sf:=true
end;
if not sf then

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