Explorați Cărți electronice
Categorii
Explorați Cărți audio
Categorii
Explorați Reviste
Categorii
Explorați Documente
Categorii
Prelucrarea fişierelor binare care necesită actualizare trebuie să asigure posibilitatea ştergerii
articolelor şi să elimine riscul de suprascriere a articolelor adăugate. Pentru aceasta, trebuie proiectate
structuri particulare de articole şi concepute operaţii de gestiune specifice. Organizarea fişierelor care
asigură identificarea articolelor prin numărul lor relativ, se numeşte organizare relativă.
Fără a epuiza multitudinea soluţiilor de rezolvare a problemelor de gestiune a fişierelor care
necesită actualizare, în continuare, se prezintă câteva dintre ele. În orice situaţie, limitările de regăsire
prin acces secvenţial sau relativ a articolelor în fişier reduc aria folosirii limbajului în probleme de
gestiune. Marele inconvenient îl constituie lipsa accesului după cheie, cel care corespunde cel mai bine
gestiunii în sistemele reale.
Pentru a simula organizarea relativă în Pascal se poate utiliza o codificare externă a cheilor
relative (numerelor relative) ale articolelor, prin utilizarea unui nomenclator de articole, care să conţină
numărul relativ al fiecăruia dintre ele. Nomenclatorul este elaborat extern (automat sau neautomat).
Orice operaţie de regăsire în acces relativ presupune introducerea din exterior a numărului relativ. La
crearea iniţială, fiecare articol este înscris la numărul său relativ predefinit. Asigurarea ştergerii şi
adăugării controlate poate fi făcută în diverse moduri:
♦ Extinderea articolelor logice cu un indicator de stare (un octet), ajungându-se la forma din
figura 6.1.
Indicatorul de stare (notat is) va avea o valoare din două posibile (de exemplu, 0 pentru articol
inactiv - inexistent sau şters -, 1 pentru articol prezent);
Cu această structură, operaţiile de acces la articole se realizează în următoarele condiţii:
scrierea în fişier este permisă numai pentru articolele cu is=0; citirea din fişier este permisă numai
pentru articolele cu is=1.
• Preformarea presupune deschiderea fişierului ca nou şi crearea unui număr de articole (la
limită, zero) cu is=0. Includerea operaţiei de preformare conduce la dispariţia distincţiei dintre populare
şi adăugare. Datorită faptului că fişierul se deschide ca existent, orice operaţie de scriere a unui nou
articol se tratează ca adăugare. într-un sistem de programe, deschiderea cu Rewrite a unui fişier se
realizează o singură dată, în procedura de preformare.
• Scrierea în acces direct presupune furnizarea numărului relativ (nr) al articolului. În funcţie
de valoarea lui nr se disting următoarele situaţii:
- dacă nr<FileSize(f), se citeşte articolul respectiv din fişier şi adăugarea este permisă numai
dacă is=0;
- dacă nr>=FileSize(f), are loc extinderea fişierului cu preformarea articolelor cu numerele
relative cuprinse în domeniul FileSize(f)..nr-1. Noul articol se scrie pe poziţia nr.
Se remarcă faptul că scrierea în acces direct permite preformarea iniţială cu zero articole.
• Scrierea în acces secvenţial se face fără verificare de inexistenţă. Scrierea are loc în poziţia
dată de pointerul curent. Procedura face is=1. Utilizarea ei se recomandă numai la popularea densă.
• Citirea în acces direct presupune furnizarea numărului relativ (nr). Ea verifică dacă is=1.
• Citirea în acces secvenţial analizează articolele începând cu cel de la pointerul curent. Artico-
lele cu is=0 sunt ignorate, până la întâlnirea primului articol cu is=1 sau până se ajunge la sfârşit de
fişier.
• Ştergerea se realizează în acces direct. Ea presupune citirea articolului şi dacă ştergerea este
permisă (is=1), se modifică indicatorul de stare (is=0) şi se scrie articolul pe vechiul loc.
Algoritmi şi programe de prelucrare a fişierelor
• Rescrierea realizează scrierea unui articol în poziţia FilePos(f)-1, dacă vechiul articol din
această poziţie are is=1.
♦ Folosirea articolului zero ca tabelă de ocupare în fişier. Fiecărui articol din fişier îi cores-
punde câte un octet în primul articol: articolului cu numărul relativ i îi corespunde octetul a[i]. Primul
articol are structura a:ARRAY[1..max] OF BYTE, unde max este o constantă care indică numărul
maxim de articole pe care le poate avea fişierul pe durata existenţei sale. Dacă articolul i este prezent,
a[i]=1; dacă articolul i este inactiv (inexistent sau şters), a[i]=0.
Cu această structură, operaţiile de acces la articole se realizează în următoarele condiţii:
scrierea în fişier a articolului cu numărul relativ i este permisă numai dacă a[i]=0; citirea din fişier a
articolului cu numărul relativ i este permisă numai dacă a[i]=1.
Ştergerea articolului i presupune verificarea existenţei sale (a[i]=1) şi realizarea operaţiei
a[i]=0. Adăugarea unui articol i presupune verificarea inexistenţei lui (a[i]=0), înscrierea articolului şi
realizarea operaţiei a[i]=1.
Utilizarea acestei modalităţi necesită încărcarea iniţială în memoria principală a articolului cu
numărul relativ zero. În programele care realizează ştergeri sau/şi adăugări, înainte de închiderea
fişierului trebuie reînscris articolul zero. Pentru ca metoda să fie eficientă, articolul zero trebuie să aibă
lungime cel mult egală cu lungimea articolelor de date. Se pot concepe algoritmi prin care, pentru
tabela de ocupare în fişier, se alocă spaţiu mai mic, fiecărui articol corespunzându-i un bit, în loc de un
octet.
Observaţii:
1. Programul oferă utilizatorului funcţiuni de Creare, Adăugare, Modificare şi Ştergere, realizate
în acces direct după cheia relativă. În meniul afişat pe ecran există şi funcţiunea de terminare a
programului.
2. Funcţiunile de Creare şi Adăugare sunt identice, cu deosebirea că pentru prima fişierul se
deschide ca nou (cu Rewrite), iar pentru cea de-a doua fişierul se deschide ca existent (cu
Reset).
3. La opţiunea de ştergere s-a inclus o confirmare suplimentară din partea utilizatorului, pentru
cazul în care cheia relativă introdusă de la tastatură există în fişier, dar nu aparţine angajatului
care se doreşte a fi şters.
4. Funcţiunea de modificare prevede posibilitatea modificării valorii oricărui câmp sau combinaţie
de câmpuri. Prin convenţie, tastarea doar lui <ENTER> semnifică nemodificarea câmpului
respectiv.
5. Fiecare funcţiune a programului prevede posibilitatea reluării ei în interior, fără a mai ieşi în
meniul principal. Terminarea unei funcţiuni se realizează prin tastarea caracterului CTRL-Z în
Algoritmi şi programe de prelucrare a fişierelor
câmpul marca (sfârşit standard al tastaturii). De aceea, la revenirea în meniul principal şi la
apelul unei noi funcţiuni, tastatura (fişier TEXT standard de intrare) trebuie deschisă cu
procedura Reset(Input).
program actualizare_fisier_relativ;
uses crt;
type
art=record
is:0..1;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
var
f:file of art;
x:art;
opt,r:char;
marca,i,err:word;
aux:string[20];
procedure meniu;
begin
reset(input); clrscr;
gotoxy(30,7); write('Functiunile programului');
gotoxy(36,9); write('1. Creare');
gotoxy(36,10); write('2. Adaugare');
gotoxy(36,11); write('3. Modificare');
gotoxy(36,12); write('4. Stergere');
gotoxy(36,13); write('5. Terminare');
gotoxy(30,16); write('Functia aleasa:');
gotoxy(46,16); readln(opt);
end;
procedure citire_campuri;
begin
write('Nume si prenume: '); readln(x.nume);
write('Profesie: '); readln(x.prof);
write('Loc de munca: '); readln(x.loc);
write('Salariu: '); readln(x.sal);
x.is:=1
end;
procedure preformare;
begin
seek(f,filesize(f));
x.is:=0;
for i:=filesize(f) to marca-1 do write(f,x)
end;
procedure creare;
begin
reset(input); assign(f,'pers.dat');
if opt='1' then rewrite(f) else reset(f);
checkeof:=true; clrscr;
with x do begin
Algoritmi şi programe de prelucrare a fişierelor
write('Marca: ');
while not eof do
begin
readln(marca);
if marca<filesize(f) then
begin
seek(f,marca); read(f,x);
if is=0 then
begin
citire_campuri;
seek(f,marca);
write(f,x)
end
else writeln('Marca alocata altui angajat !')
end
else begin
preformare;
citire_campuri;
write(f,x)
end;
write('Marca (sau ^Z): ')
end;
end;
close(f);
end;
procedure stergere;
begin
reset(input); assign(f,'pers.dat'); reset(f);
checkeof:=true; clrscr;
with x do begin
write('Marca: ');
while not eof do
begin
readln(marca);
if marca<filesize(f) then
begin
seek(f,marca); read(f,x);
if is=1 then
begin
writeln(nume,' ',loc,' ',prof);
write('Confirmati stergerea ? (d/n): ');
readln(r);
if upcase(r)='D' then
begin
is:=0;
seek(f,marca);
write(f,x)
end
end
else writeln('Angajat inexistent in fisier !')
end
else writeln('Marca eronata !');
Algoritmi şi programe de prelucrare a fişierelor
write('Marca (sau ^Z): ')
end;
end;
close(f);
end;
procedure modif_campuri;
begin
with x do begin
write('Nume si prenume: ',nume,' '); readln(aux);
if aux<>'' then nume:=aux;
write('Profesie: ',prof,' '); readln(aux);
if length(aux)<>0 then prof:=aux;
write('Loc de munca: ',loc,' '); readln(aux);
if aux[0]<>#0 then val(aux,loc,err);
write('Salariu: ',sal,' '); readln(aux);
if aux[0]<>#0 then val(aux,sal,err);
seek(f,marca); write(f,x)
end
end;
procedure modificare;
begin
reset(input); assign(f,'pers.dat'); reset(f);
checkeof:=true; clrscr;
with x do begin
write('Marca: ');
while not eof do
begin
readln(marca);
if marca<filesize(f) then
begin
seek(f,marca); read(f,x);
if is=1 then modif_campuri
else writeln('Angajat inexistent in fisier !')
end
else writeln('Marca eronata !');
write('Marca (sau ^Z): ')
end;
end;
close(f);
end;
program vizualizare_angajat;
uses crt;
type
art=record
is:0..1;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
var
f:file of art;
x:art;
marca:word;
vb:boolean;
begin
assign(f,'pers.dat'); reset(f);
checkeof:=true; clrscr;
with x do begin
gotoxy(30,10); write('Marca: ');
while not eof do
begin
readln(marca);
if marca<filesize(f) then
begin
seek(f,marca); read(f,x);
if is=1 then
begin
gotoxy(25,15);
writeln(nume,' ',prof,' ',loc,' ',sal)
end
else
begin
gotoxy(30,12);
writeln('Angajat inexistent in fisier !',#7)
end
end
else
begin
gotoxy(30,12);
writeln('Marca eronata !',#7)
end;
Algoritmi şi programe de prelucrare a fişierelor
readln; clrscr; gotoxy(30,10);
write('Marca(sau ^Z): ')
end
end;
close(f)
end.
program vizualizare_profesie;
uses crt;
type
art=record
is:0..1;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
var
f:file of art;
x:art;
prof_t:string[10];
aux:string[20];
vb,sw:boolean;
i:byte;
begin
assign(f,'pers.dat'); reset(f);
checkeof:=true; clrscr;
sw:=true; i:=0;
with x do begin
write('Profesia: ');
while not eof do
begin
readln(prof_t);
seek(f,0); sw:=true; i:=0;
vb:=false;
while not eof(f) do
begin
read(f,x);
if (is=1) and (prof=prof_t) then
begin
if sw then
begin
Algoritmi şi programe de prelucrare a fişierelor
gotoxy(20,10);
writeln('Marca Nume si prenume Loc Salariu');
sw:=false
end;
inc(i); gotoxy(20,12+i); fillchar(aux,21,' ');
aux:=nume; aux[0]:=#20;
writeln((filepos(f)-1):5,' ',aux,' ',loc:3,' ',sal:7);
vb:=true
end
end;
if not vb then
begin
gotoxy(30,15);
writeln('Profesie inexistenta !',#7)
end;
readln; clrscr; write('Profesia (sau ^Z): ')
end
end;
close(f)
end.
Exerciţiul 4: Să se realizeze programul pentru afişarea informaţiilor existente despre toţi angajaţii,
în ordine alfabetică a numelui şi grupaţi pe profesii. Se va utiliza fişierul creat la exerciţiul 1.
Observaţii:
1. Pentru a obţine lista dorită, fişierul de date trebuie sortat după două chei. Cheia principală este
profesia, iar cheia secundară este numele şi prenumele.
2. Pentru a nu afecta organizarea relativă, sortarea se va realiza într-un fişier de manevră, organizat
secvenţial, cu memorare densă. Structura articolului asociat manevrei este structura logică a
fişierului de date. Valorile câmpului marca sunt date de poziţia curentă a articolului în fişierul
iniţial. La sfârşitul programului, fişierul de manevră va fi şters din director.
3. Pentru a obţine lista pe mediu magnetic (pentru imprimări ulterioare), în program se va modica
afişarea pe ecran cu scrierea într-un fişier TEXT magnetic.
program sortare_dupa_doua_campuri;
uses crt;
type
artf=record
is:0..1;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
artm=record
marca:word;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
var
f:file of artf;
Algoritmi şi programe de prelucrare a fişierelor
m:file of artm;
z:artf; x,y:artm;
n,i,j:word;
aux1:string[10];
aux2:string[20];
procedure creare_manevra;
begin
assign(f,'pers.dat'); reset(f);
assign(m,'manevra.tmp'); rewrite(m);
while not eof(f) do
begin
read(f,z);
if z.is=1 then
begin
x.marca:=filepos(f)-1;
x.nume:=z.nume;
x.prof:=z.prof;
x.loc:=z.loc;
x.sal:=z.sal;
write(m,x)
end
end;
close(f)
end;
procedure sortare_manevra;
begin
n:=filesize(m);
for i:=1 to n-1 do
begin
seek(m,i-1); read(m,x);
for j:=i+1 to n do
begin
seek(m,j-1); read(m,y);
if x.prof>y.prof then
begin
seek(m,i-1); write(m,y);
seek(m,j-1); write(m,x);
x:=y
end
else if x.prof=y.prof then
if x.nume>y.nume then
begin
seek(m,i-1); write(m,y);
seek(m,j-1); write(m,x);
x:=y
end
end
end
end;
procedure listare_manevra;
begin
with x do begin
Algoritmi şi programe de prelucrare a fişierelor
seek(m,0); i:=0;
clrscr; gotoxy(25,2);
writeln('Tabel cu angajatii pe profesii');
gotoxy(17,4);
writeln(' PROFESIE MARCA NUME SI PRENUME LOC’,
‘ SALARIU');
while not eof(m) do
begin
read(m,x);
fillchar(aux1,11,#32); aux1:=prof; aux1[0]:=#10;
fillchar(aux2,21,#32); aux2:=nume; aux2[0]:=#20;
gotoxy(17,6+i); inc(i);
writeln(aux1,' ',marca:4,' ',aux2,' ',loc:3,' ',sal:7)
end
end;
close(m); erase(m)
end;
begin
creare_manevra;
sortare_manevra;
listare_manevra
end.
program modificare_secventiala;
uses crt;
type
art=record
is:0..1;
nume:string[20];
prof:string[10];
loc:byte;
sal:longint
end;
var
f:file of art;
x:art;
indice:real;
begin
assign(f,'pers.dat'); reset(f);
with x do begin
write('Indicele de crestere (%): ');
readln(indice);
while not eof(f) do
begin
read(f,x);
if is=1 then
begin
sal:=trunc(sal*(1+indice/100));