Algoritmi de prelucrare a fiierelor organizate secvenial
Din punct de vedere al operaiilor de gestiune solicitate de diverse aplicaii, fiierele binare se pot grupa n fiiere care nu sunt actualizate (inute la zi) i fiiere care sunt actualizate. De obicei, fiierele din prima grup se regsesc n aplicaii matematice sau ca fiiere temporare i de tranzacii n aplicaii de gestiune economic. Fiierele din cea de-a doua grup sunt, de obicei, fiiere permanente (principale) n aplicaii de gestiune economic i au particulariti de proiectare, referitoare, n special, la asigurarea tergerii i adugrii de articole. Asupra fiierelor binare care nu necesit actualizare se realizeaz, de obicei, operaiile de creare (populare) i consultare. Dintre operaiile de actualizare pot fi realizate, fr mari complicaii, modificarea i adugarea dens de articole.
Popularea fiierelor se realizeaz prin preluarea datelor fie din alte fiiere, fie de la tastatur (popularea interactiv). n ultimul caz, cel mai des ntlnit n practic, fiierul conductor corespunde mulimii datelor introduse de la tastatur. Articolele sunt preluate cmp cu cmp, neexistnd posibilitatea citirii unei variabile de tip articol i, n plus, introducerea unei date este adesea nsoit de proceduri de validare specifice, cu reintroducerea ei n cazul unei erori. Sfritul introducerii datelor de la tastatur (i implicit a procesului de populare a fiierului) poate fi: - De tip chestionar, prin consultarea utilizatorului, privind continuarea sau nu a introducerii articolelor. Pentru un volum mare de date, varianta prezint dezavan- tajul mririi timpului de prelucrare. - Convenional, prin introducerea pentru primul cmp din articol a unei valori prestabilite, cu semnificaie de sfrit de prelucrare. - Standard, prin tastarea caracterului CTRL/Z, cu rol de sfrit de fiier TEXT, caz n care variabilei standard CheckEof (definit n unitatea standard CRT) trebuie s i se atribuie n program valoarea TRUE. O alt problem a populrii fiierelor binare o reprezint aezarea articolelor pe suportul extern. Din acest punct de vedere se ntlnesc dou modaliti: Populare dens, prin care articolele se scriu unul dup altul, n ordinea n care au fost furnizate, fr a se lsa locuri libere (acces secvenial). Pentru fiierele care nu necesit actualizare acesta este tipul recomandat. Populare aleatoare, prin care articolele sunt scrise pe poziiile al cror numr relativ este furnizat explicit de programator (acces direct). Scrierea unui articol se realizeaz dup poziionarea pe numrul relativ dorit, cu procedura Seek(f,nr_relativ). La populare, nr_relativ nu este limitat dect de spaiul existent pe suportul extern. Metoda are dezavantajul c necesit evidena "articolelor vide". n cazul fiierelor care nu necesit actualizare, popularea aleatoare se recomand numai dac, dup creare, fiierul este dens.
Algoritmi n programare. Aplicaii Exerciiul 6.1. S se realizeze programul pentru crearea unui fiier secvenial care memoreaz datele referitoare la facturile emise de ctre o societate comercial, ntr-un anumit an. Structura articolului este urmtoarea:
Data emiterii Numr factur lun zi Denumire beneficiar Cod fiscal Valoare facturat TVA facturat String[10] 1..12 1..31 String[20] Longint Real Real
Datele se introduc de la tastatur, cmp cu cmp, fr validare. Sfritul introducerii este standard (se tasteaz <CTRL/Z> n cmpul nr_fact). Programul de creare a fiierului 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:'); Algoritmi de prelucrare a fiierelor organizate secvenial Gotoxy(40,17); Readln(tva); Write(f,factura); clrscr; Gotoxy(15,9); Write('Nr. factura: '); Gotoxy(40,9) End {while}; Close(f) End {with} End.
Consultarea fiierelor are mai multe variante, n funcie de scopul prelu- crrii. Dup modul de regsire a articolelor n cadrul fiierului, consultarea poate fi secvenial, direct sau mixt. Consultarea secvenial presupune regsirea articolelor n ordinea n care sunt memorate pe suportul extern. Dup numrul articolelor prelucrate, consultarea secvenial poate fi: integral, cnd se prelucreaz toate articolele fiierului; cu selecie, cnd se prelucreaz numai acele articole care au una sau mai multe caracteristici comune. Dup numrul de caracteristici, selecia poate fi simpl, dubl, multipl. Pentru consultarea secvenial se poate utiliza oricare din tipurile de algoritmi de prelucrare cu fiier conductor 1 .
Exemplu: Obinerea unei situaii cu mai multe grade de total. Pentru aceasta se stabilesc cmpuri, numite caracteristici de grupare sau caracteristici de control, asociate gradelor de total. O caracteristic de control este un cmp al articolului din fiierul de date, care are aceeai valoare pentru mai multe nregistrri. Astfel, articolele care au valoare comun pentru o caracteristic de grupare se pot ordona pe submulimi, formnd o grup de control. Fiierul poate constitui, n ansamblul su, caracteristica de grupare de cel mai nalt nivel, pentru care se poate calcula totalul general. Numrul maxim de grade de total este superior cu unu numrului de caracteristici de control stabilite. ntre caracteristicile de grupare se stabilete o relaie de ordine ierarhic. Pentru prelucrarea fiierului, cu utilizare minim de memorie, articolele trebuie sortate dup caracteristicile de control. Acest tip de prelucrare intr n categoria consultrilor secveniale integrale. Prelucrarea unui fiier sortat dup criteriile enunate presupune existena unor operaii standard, executate la schimbarea valorii fiecrei caracteristici de control stabilite: operaii iniiale ale unei grupe de control prin care se iniializeaz variabila de total specific grupei; se salveaz valoarea caracteristicii primului articol din grup; alte operaii iniiale specifice grupei; operaii finale ale unei grupe de control prin care se afieaz totalul calculat pentru caracteristica ce se schimb; se cumuleaz totalul grupei curente la totalul grupei ierarhic superioar; alte operaii finale specifice grupei; condiia de prelucrare a unei grupe de control conine, pe lng condiia specific, toate celelalte condiii din amonte.
1 Figurile 15.2 - 15.6, capitolul Algoritmi de prelucrare a fiierelor binare din lucrarea Algoritmi n programare, B. Ghilic-Micu (coord.), Ed. ASE, Bucureti 2002, pag. 235-238 Algoritmi n programare. Aplicaii Raportul final este listat la imprimant, fie direct, ca fiier de ieire, fie creat pe suport magnetic, ca fiier TEXT, n vederea imprimrii ulterioare. Structura unei pagini a raportului i controlul trecerii la o nou pagin trebuie asigurate de programator. n continuare se prezint structura de principiu 2 a unui program de obinere a unui raport final, cu control dup dou caracteristici i trei grade de total, unde camp_1 i camp_2 sunt caracteristicile de control (cmpuri 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 oricte 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 capului de tabel *) 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;
2 n exemple, comentariile incluse ntre perechile de caractere (* i *) sugereaz existena unei secvene de program, iar cele incluse ntre caracterele { } sunt comentarii propriu-zise. Algoritmi de prelucrare a fiierelor organizate secvenial 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; {programul principal} begin inceput; while not sf do prel_1; sfarsit end.
Exerciiul 6.2. S se realizeze programul pentru obinerea unei liste cu valoarea lunar facturat i TVA-ul aferent, pentru fiecare beneficiar ctre care au fost emise facturi, utiliznd informaiile memorate n fiierul creat prin programul prezentat n exerciiul 6.1. Numrul i denumirile beneficiarilor sunt necunoscute la momentul proiectrii. Schema de sistem este prezentat n figura 6.1. Programul Consultare este structurat pe trei module: modulul Creare_manevra (1) copiaz ntr-un fiier intermediar (fiier de manevr) informaiile utile obinerii situaiei de ieire, n vederea sortrii lor; modulul Sortare_manevra (2) realizez sortarea fiierului de manevr prin metoda seleciei, dup valoarea cmpului den_benef; modulul Listare (3) realizeaz obinerea situaiei finale ntr-un fiier magnetic de tip TEXT.
Facturi.dat Manevra.tmp Tabel.txt 1 2 3
CONSULTARE
Fig. 6.1. Schema de sistem a programului de consultare
Algoritmi n programare. Aplicaii 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); 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 Algoritmi de prelucrare a fiierelor organizate secvenial 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 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; Algoritmi n programare. Aplicaii Close(manevra); Erase(manevra); Close(lista) end End; {programul principal} Begin Creare_manevra; Sortare_manevra; Listare End.
Consultarea n acces direct presupune regsirea articolului dup numrul relativ, prin secvena Seek(f,nr_relativ); Read(f,art). Numrul relativ este furnizat de utilizator i trebuie s aparin domeniului 0..FileSize(f)-1. Se remarc faptul c dac nr_relativ depete dimensiunea fiierului, procedura Seek nu genereaz eroare, dar citirea va determina ntreruperea execuiei programului. Pentru evitarea acestei situaii se va include n program validarea apartenenei numrului relativ la intervalul acceptat. Algoritmul de consultare n acces direct a unui fiier are un alt fiier conductor (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); {citire numar relativ} seek(f,r); {$i-} read(f,art); {$i+} {citire articol in acces direct} if ioresult = 0 then (* prelucrare articol *) else writeln('Articol inexistent !'); write('Nr. relativ (sau ctrl-z): ') end; close(f) end.
Consultarea n acces mixt utilizeaz o combinaie ntre accesul direct i cel secvenial, n vederea prelucrrii unui grup de articole, memorate contiguu n fiier i selectabile printr-o condiie. Pentru fiierele binare, metoda poate fi aplicat dac se dorete selectarea articolelor dintre dou limite ale numerelor relative: limita inferioar (l i ) i limita superioar (l s ). Algoritmul trebuie s verifice relaia 0l i l s <FileSize(f), dup care parcurgerea fiierului poate fi realizat prin orice tip de structur repetitiv. Algoritmi de prelucrare a fiierelor organizate secvenial Exemplu: begin (* citire nume fisier extern *) assign(f,nume_fisier); reset(f); write('limita inferioara: '); readln(li); { citirea nr. relativ al primului articol } write('limita superioara: '); readln(ls); { citirea nr. relativ al ultimului articol } 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.
Adugarea de articole se realizeaz, n general, cu tranzacii de la tastatur, similar operaiei de populare. Pentru o corect exploatare ulterioar, adugarea trebuie s fie dens. Acest lucru poate fi realizat astfel: Adugare la sfrit (extindere), dup ultimul articol scris. Operaia se realizeaz similar populrii n acces secvenial, dup poziionarea pe marcatorul de sfrit de fiier, cu procedura Seek(f,FileSize(f)).
Exemplu: begin (* citire nume fisier extern *) assign(f,nume_fisier); reset(f); {pozitionare dupa ultimul articol scris} seek(f,filesize(f)); 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. Algoritmi n programare. Aplicaii Inserarea unor articole. Se aplic n cazul n care articolele sunt scrise n fiier n ordinea cresctoare (descresctoare) a valorilor unui anumit cmp. n acest caz, noul articol va fi inserat ntre dou articole, astfel: - se caut (cu un algoritm secvenial, binar etc.) poziia k n care trebuie inserat noul articol; - se copiaz, glisnd cu o poziie spre dreapta, toate articolele de la sfritul fiierului pn la articolul cu numrul relativ k; - se scrie n acces direct noul articol, n poziia k.
Exemplu: {articolele 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 pot adauga mai multe articole} begin {introducerea campului dupa care sunt sortate articolele} readln(art_nou.camp_1); (* preluare de la tastatura a celorlalte campuri din articolul de adaugat *) {cautarea 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 {$I+} read(f,art_existent); {$I-} if ioresult <> 0 then sf:=true end; if not sf then begin k:=filepos(f)-1;{articolul se va insera in pozitia k } for i:=filesize(f)-1 downto k do begin seek(f,i); read(f,art_existent); write(f,art_existent) end end else k:=filesize(f); {articolul se adauga la sfarsit} seek(f,k); write(f,art_nou); write('camp 1: ') end; close(f) end. Algoritmi de prelucrare a fiierelor organizate secvenial Modificarea valorii unor cmpuri din articol se realizeaz n mai multe etape: - se citete articolul care se modific (Seek i Read); - se modific (n zona articol din memoria principal) cmpurile cu valorile dorite, introduse, n general, de la tastatur; - se repoziioneaz pe articolul respectiv cu Seek(f,FilePos(f)-1); - se scrie articolul modificat, cu procedura Write. O problem important rmne selectarea cmpurilor care se modific, pentru fiecare articol n parte. O variant simpl este afiarea vechii valori, urmat de introducerea noii valori, n variabile independente de tip STRING. n cazul n care irul introdus este vid (s-a tastat numai <ENTER>), respectivul cmp, prin convenie, nu se modific. Altfel, cmpului respectiv i se va atribui valoarea citit n variabila independent, eventual prin conversie cu procedura VAL, pentru cmpurile numerice.
Exemplu: (* cautare articol de modificat *) read(f,art); write('Codul: ',art.cod,' '); {afisare vechea valoare} readln(cods); {citire noua valoare; cods este de tip string} if length(cods)<>0 then val(cods,art.cod,err); {conversie din ASCII in binar} write('Denumire: ',art.den,' '); {afisare vechea valoare} readln (dens); {citire noua valoare} if length(dens) <> 0 then art.den:=dens; {atribuire noua valoare} (* introducerea celorlalte campuri din articol *) seek(f,filepos(f)-1); {repozitionare pe articol} write(f,art) {rescriere articol modificat }
O alt variant se poate realiza prin folosirea unei machete de ecran n care se afieaz valorile actuale ale fiecrui cmp de modificat, se poziioneaz succesiv cursorul la nceputul fiecrui cmp, cu dou rspunsuri posibile ale utilizatorului: <ENTER>, caz n care se menine actuala valoare, respectiv o tast diferit de <ENTER>, reprezentnd primul caracter al noii valori.
Exerciiul 6.3. S se realizeze programul pentru crearea unui fiier secvenial Produse.dat, care memoreaz datele referitoare la produsele fabricate de ctre o ntreprindere, ntr-un an. Structura articolului este urmtoarea:
Cantitate lunar Cod produs Denumire produs Cod depozit Pre unitar mediu 1 2 12 byte String[30] char longint word word word
Datele se introduc de la tastatur, cmp cu cmp, asigurndu-se urmtoarele validri: Algoritmi n programare. Aplicaii - codul produsului s fie numeric; - denumirea produsului s fie alfabetic (format numai din litere mari, litere mici i spaii); - codul depozitului s fie o liter ; - preul unitar s fie numeric i mai mare sau egal cu 100; - cantitile lunare s fie numerice. n cazul n care o dat nu ndeplinete condiiile impuse, se semnaleaz eroarea i se reia introducerea. Sfritul introducerii este standard (se tasteaz <CTRL/Z> n cmpul cod).
program creare_fisier_secvential; uses crt; type produs=record cod:byte; den:string[30]; dep:char; pu:longint; cant:array[1..12] of word end; var art:produs; f:file of produs; er:boolean; i,l:byte; s:string[100]; const alfabet=['A'..'Z','a'..'z',' ']; procedure eroare; begin er:=true; gotoxy(10,25); write(s,' tastati <ENTER>',#7); repeat until readkey=#13; gotoxy(10,25); clreol; end; procedure cit_cod; begin repeat er:=false; gotoxy(38,5); {$i-}; readln(art.cod); {$i+}; if ioresult <> 0 then begin s:='Valoare nenumerica !'; eroare; gotoxy(38,5); clreol end until not er end; Algoritmi de prelucrare a fiierelor organizate secvenial procedure cit_den; begin repeat er:=false; gotoxy(38,6); clreol; readln(art.den); l:=length(art.den); for i:=1 to l do if not (art.den[i] in alfabet) then er:=true; if er then begin s:='Caractere nealfabetice !'; eroare end until not er end; procedure cit_dep; begin repeat er:=false; gotoxy(38,7); clreol; readln(art.dep); if not (upcase(art.dep)in ['A'..'Z']) then begin s:='Cod depozit eronat !'; eroare end until not er end; procedure cit_pret; begin repeat er:=false; gotoxy(38,8); clreol; {$i-} readln(art.pu); {$i+} if ioresult<>0 then begin s:='Caractere nenumerice !'; eroare end else if art.pu < 100 then begin s:='Pret < 100 !'; eroare end until not er end; procedure cit_cant; begin repeat er:=false; gotoxy(38,i+8); clreol; {$i-} readln(art.cant[i]); {$i+} if ioresult<>0 then begin Algoritmi n programare. Aplicaii s:='Caractere nenumerice !'; eroare end until not er end; procedure inceput; begin textbackground(magenta); textcolor(yellow); clrscr; assign(f,'produse.dat'); rewrite(f); checkeof:=true; gotoxy(20,5); write('Cod (sau ^Z): '); gotoxy(20,6); write('Denumire : '); gotoxy(20,7); write('Cod depozit: '); gotoxy(20,8); write('Pret mediu : '); for i:=1 to 12 do begin gotoxy(20,i+8); write('Cant. luna ',i:2,' : ') end; gotoxy(38,5) end; procedure prelucrare; begin cit_cod; cit_den; cit_dep; cit_pret; for i:=1 to 12 do cit_cant; write(f,art); for i:=5 to 20 do begin gotoxy(38,i); clreol end; gotoxy(38,5) end; procedure sfarsit; begin close(f) end; {programul principal} begin inceput; while not eof do prelucrare; sfarsit end.
Exerciiul 6.4. S se realizeze programul pentru afiarea pe monitor a denumirii i a produciei valorice anuale pentru produsele existente n fiierul Produse.dat, ale cror coduri se introduc de la tastatur. Sfritul introducerii de la tastatur se marcheaz standard (^Z n cmpul cod). Observaii: Deoarece codul produselor are valori unice, cutarea se realizez pn cnd se regsete un articol al crui cod produs este egal cu valoarea introdus de la tastatur, caz n care se calculeaz valoarea anual i se afieaz, sau pn la sfritul fiierului, caz n care produsul cutat nu exist n fiier i se afieaz un mesaj corespunztor. Pentru fiecare nou cod, cutarea se realizeaz de la nceputul fiierului. Algoritmi de prelucrare a fiierelor organizate secvenial program consultare_dupa_camp_cu_valoare_unica; uses crt; type produs=record cod:byte; den:string[30]; dep:char; pu:longint; cant:array[1..12] of word end; var art:produs; f:file of produs; vb:boolean; cod_t,i:byte; v:real; begin assign(f,'produse.dat'); reset(f); clrscr; checkeof:=true; gotoxy(27,5); write('Codul produsului: '); while not eof do begin gotoxy(50,5); readln(cod_t); seek(f,0); vb:=false; while not vb and not eof(f) do begin read(f,art); if art.cod = cod_t then begin v:=0; for i:=1 to 12 do v:=v+art.cant[i]; v:=v*art.pu; gotoxy(27,12); writeln('Denumire',' ':10,'Valoare'); gotoxy(25,15); writeln(art.den,' ':5,v:10:0,' lei'); readln; vb:=true end end; if not vb then begin gotoxy(30,15); writeln('Cod produs eronat !',#7) end; clrscr; gotoxy(27,5); write('Codul produsului (sau ^Z): ') end; close(f) end. Algoritmi n programare. Aplicaii Exerciiul 6.5. S se realizeze programul pentru afiarea pe monitor a denumirii i a produciei valorice anuale pentru produsele existente n fiierul Produse.dat, aflate n depozitele ale cror coduri se introduc de la tastatur. Sfritul introducerii de la tastatur se marcheaz standard (^Z n cmpul dep). Observaii: Deoarece ntr-un depozit se afl mai multe produse (cmpul dep are valori duplicate), cutarea se realizez de la nceputul pn la sfritul fiierului pentru fiecare nou cod de depozit introdus. n cazul n care nici un produs nu are codul depozitului egal cu valoarea introdus de la tastatur, se afieaz un mesaj corespunztor i procesul se reia. Existena sau inexistena a cel puin unui produs n depozitul cutat este marcat cu o variabil semafor, care este i contor (k).
program consultare_dupa_camp_cu_valoare_duplicata; uses crt; type produs=record cod:byte; den:string[30]; dep:char; pu:longint; cant:array[1..12] of word end; var art:produs; f:file of produs; sir:string[30]; dep_t:char; i,k:byte; v:real; begin assign(f,'produse.dat'); reset(f); clrscr; checkeof:=true; gotoxy(27,5); write('Codul depozitului: '); while not eof do begin gotoxy(50,5); readln(dep_t); seek(f,0); k:=0; while not eof(f) do begin fillchar(sir,31,' '); read(f,art); if art.dep=dep_t then begin inc(k); v:=0; for i:=1 to 12 do v:=v+art.cant[i]; v:=v*art.pu; gotoxy(10,12); Algoritmi de prelucrare a fiierelor organizate secvenial writeln('Cod',' ':10,'Denumire', ' ':25,'Valoare'); gotoxy(10,14+k); sir:=art.den; sir[0]:=#30; writeln(art.cod:3,' ':10,sir,' ', v:10:0,' lei') end end; if k=0 then begin gotoxy(30,15); writeln('Cod depozit eronat !',#7) end; readln; clrscr; gotoxy(27,5); write('Codul depozitului (sau ^Z): ') end; close(f) end.
Exerciiul 6.6. S se realizeze programul pentru afiarea pe monitor a produciei valorice anuale pentru fiecare depozit i pe ntreprindere, utiliznd fiierul Produse.dat. Observaii: Problema se rezolv cu ajutorul algoritmului de consultare secvenial cu control dup o caracteristic. Pentru obinerea situaiei cerute se creeaz un fiier de manevr, care va conine date privind codul depozitului i stocul valoric anual pentru toate produsele existente n fiierul de date. Fiierul de manevr se sorteaz dup cmpul depm, apoi este consultat secvenial i integral dup aceast caracteristic, obinndu-se dou grade de total: unul pentru depozit i unul pentru ntreprindere.
program consultare_cu_control_dupa_caracteristica; uses crt; type artf=record cod:byte; den:string[30]; dep:char; pu:longint; cant:array[1..12] of word end; artm=record depm:char; v:real end; var z:artf; x,y:artm; f:file of artf; m:file of artm; i,j:byte; totgen,totdep:real; vb,sf:boolean; c:char; Algoritmi n programare. Aplicaii procedure copiere; begin assign(f,'produse.dat'); reset(f); assign(m,'manevra.tmp'); rewrite(m); with z,x do begin while not eof(f) do begin read(f,z); v:=0; for i:=1 to 12 do v:=v+cant[i]; v:=v*pu; depm:=dep; write(m,x) end end; close(f) end; procedure sortare; begin repeat vb:=false; for i:=1 to filesize(m)-1 do begin seek(m,i-1); read(m,x,y); if x.depm>y.depm then begin seek(m,i-1); write(m,y,x); vb:=true end end until not vb end; procedure afisare; begin seek(m,0); sf:=false; totgen:=0; i:=0; clrscr; gotoxy(5,3); writeln('Stocul valoric pe depozite'); gotoxy(9,6); writeln('Depozit Stoc'); read(m,x); while not sf do begin totdep:=0; c:=x.depm; while (x.depm=c) and not sf do begin totdep:=totdep+x.v; if eof(m) then sf:=true else read(m,x) end; Algoritmi de prelucrare a fiierelor organizate secvenial inc(i); gotoxy(12,7+i); writeln(c,' ':5,totdep:10:0,' lei'); totgen:=totgen+totdep end; gotoxy(9,9+i); writeln('Total = ',totgen:10:0,' lei'); close(m) end; {programul principal} begin copiere; sortare; afisare end.
Exerciiul 6.7. S se realizeze programul pentru crearea unui tabel cu urmtoarele informaii, despre toate produsele existente n fiierul Produse.dat: cod produs, denumire produs, pre unitar mediu, stoc anual cantitativ i stoc anual valoric. Observaii: Tabelul va fi memorat ntr-un fiier de tip TEXT, pentru listri multiple i pentru alte consideraii (de exemplu: evitarea relurii programului n cazul defectrii imprimantei, procesarea tabelului cu un editor de texte etc.).
program afisare_integrala; uses crt; type art=record cod:byte; den:string[30]; dep:char; pu:longint; cant:array[1..12] of word end; var z:art; f:file of art; l:text; linie:string[76]; d:string[30]; cant_tot:longint; valoare:real; i:byte; begin clrscr; assign(f,'produse.dat'); reset(f); assign(l,'lista.txt'); rewrite(l); with z do begin fillchar(linie,77,'='); linie[0]:=#76; writeln(l,' ':25,'TABEL CU STOCURILE DE PRODUSE'); Algoritmi n programare. Aplicaii writeln(l); writeln(l); writeln(l,' ',linie); write(l,' Cod ',' ':12,'Denumire',' ':12,' Pret '); writeln(l,' Cantitate Valoare '); writeln(l,' ',Linie); while not eof(f) do begin read(f,z); cant_tot:=0; for i:=1 to 12 do cant_tot:=cant_tot+cant[i]; valoare:=cant_tot*pu; fillchar(d,31,' '); d:=den; d[0]:=#30; write(l,' ',cod:3,' ',d,' ',pu:8,' '); writeln(l,cant_tot:9,' ',valoare:10:0,' '); writeln(l,' ',linie) end end; close(f); close(l) end.