algoritmi in programare

16
7. ALGORITMI DE PRELUCRARE A FIŞIERELOR ORGANIZATE INDEXAT Majoritatea aplicaţiilor de gestiune economică utilizează fişiere de date în care articolele trebuie regăsite după valorile unui câmp de identificare, numit cheie. Problema corespondenţei între chei şi numerele relative ale articolelor din fişierul de date se poate rezolva prin intermediul unui fişier binar suplimentar, cu rol de tabelă de indexuri. O astfel de organizare se numeşte indexată. Articolele fişierului tabelă de indexuri au structura din figura 7.1. Indicator de stare (is) Cheie Număr relativ (nr) Fig. 7.1. Structura articolului din tabela de indexuri Indicatorul de stare (is) are rol identic cu cel prezentat în capitolul referitor la fişierele organizate relativ. Cheie este un câmp în care se memorează valoarea cheii articolului existent logic în fişierul de date, al cărui număr relativ corespunzător este memorat în câmpul nr. Articolele tabelei de indexuri sunt, în orice moment, sortate crescător după valorile câmpului cheie. Articolele din fişierul de date sunt memorate aleator şi conţin câmpurile de date ale utilizatorului (pot conţine, redundant, pentru o eventuală refacere după incidente, şi valorile cheii). O parte dintre acestea nu-şi regăsesc corespondent în tabela de indexuri, fiind considerate şterse. Orice operaţie de acces la articolele fişierului de date se realizează numai prin intermediul tabelei, gestionată automat de procedurile unui unităţi specializate şi care este netransparentă utilizatorului. Operaţiile de acces la nivel de fişier sunt: deschiderea şi închiderea fişierului de date. La rândul ei, deschiderea poate fi: pentru creare (ca fişier nou) sau pentru consultare şi întreţinere (ca fişier vechi). Procedurile realizează, pe lângă operaţiile asupra fişierului de date şi gestionarea automată a tabelei de indexuri: formarea numelui său extern, asignarea numelui fizic la numele logic, deschiderea ca fişier nou sau vechi, închiderea. Operaţiile de gestiune care se pot realiza cu fişierele de date astfel organizate sunt: Crearea în acces secvenţial presupune furnizarea articolelor sortate strict crescător după valorile câmpului ales drept cheie. Articolele sunt scrise cu ajutorul procedurii de scriere în acces secvenţial. Eroarea de cheie invalidă poate apărea la tentativa de scriere a unui articol a cărui cheie este mai mică sau egală decât ultima înscrisă în fişierul de date. • Crearea în acces direct se realizează cu procedura de scriere în acces direct, articolele fiind furnizate în orice ordine. Eroarea de cheie invalidă apare la tentativa de scriere a unui articol a cărui cheie este egală cu una din cele prezente în fi şier. • Consultarea în acces secvenţial presupune regăsirea articolelor în ordinea strict crescătoare a valorilor cheii. Ea se realizează cu ajutorul procedurii de citire în acces secvenţial, care detectează şi sfârşitul fişierului de date. • Consultarea în acces mixt permite selectarea unui grup de articole, memorate logic contiguu în fişier, selecţie realizată pe baza valorilor cheii primului şi ultimului articol din grupul dorit. Accesul mixt presupune poziţionarea pe primul articol prin citirea în acces direct (sau poziţionare şi citire în acces secvenţial), urmată de exploatarea în acces secvenţial, până la găsirea cheii ultimului articol dorit, sau până la sfârşitul fişierului. • Adăugarea de articole se realizează utilizând procedura de scriere în acces direct. Articolele pot fi furnizate în orice ordine a valorilor cheii. Eroarea de cheie invalidă apare la tentativa de scriere a unui articol a cărui cheie este egală cu una deja existentă. • Modificarea unor câmpuri din articol se realizează în următoarele etape: - citirea articolului de modificat (în acces secvenţial sau direct); - modificarea, în zona articol corespunzătoare, a câmpurilor dorite, cu excepţia câmpului cheie; - rescrierea articolului, cu procedura de rescriere.

description

cap7

Transcript of algoritmi in programare

Algoritmi şi programe de prelucrare a fişierelor7. ALGORITMI DE PRELUCRARE A FIŞIERELOR

ORGANIZATE INDEXAT

Majoritatea aplicaţiilor de gestiune economică utilizează fişiere de date în care articoleletrebuie regăsite după valorile unui câmp de identificare, numit cheie. Problema corespondenţei întrechei şi numerele relative ale articolelor din fişierul de date se poate rezolva prin intermediul unui fişierbinar suplimentar, cu rol de tabelă de indexuri. O astfel de organizare se numeşte indexată. Articolelefişierului tabelă de indexuri au structura din figura 7.1.

Indicator destare (is)

Cheie Număr relativ (nr)

Fig. 7.1. Structura articolului din tabela de indexuri

Indicatorul de stare (is) are rol identic cu cel prezentat în capitolul referitor la fişiereleorganizate relativ. Cheie este un câmp în care se memorează valoarea cheii articolului existent logic înfişierul de date, al cărui număr relativ corespunzător este memorat în câmpul nr. Articolele tabelei deindexuri sunt, în orice moment, sortate crescător după valorile câmpului cheie. Articolele din fişierulde date sunt memorate aleator şi conţin câmpurile de date ale utilizatorului (pot conţine, redundant,pentru o eventuală refacere după incidente, şi valorile cheii). O parte dintre acestea nu-şi regăsesccorespondent în tabela de indexuri, fiind considerate şterse. Orice operaţie de acces la articolelefişierului de date se realizează numai prin intermediul tabelei, gestionată automat de procedurile unuiunităţi specializate şi care este netransparentă utilizatorului.

Operaţiile de acces la nivel de fişier sunt: deschiderea şi închiderea fişierului de date. La rândulei, deschiderea poate fi: pentru creare (ca fişier nou) sau pentru consultare şi întreţinere (ca fişiervechi). Procedurile realizează, pe lângă operaţiile asupra fişierului de date şi gestionarea automată atabelei de indexuri: formarea numelui său extern, asignarea numelui fizic la numele logic, deschidereaca fişier nou sau vechi, închiderea. Operaţiile de gestiune care se pot realiza cu fişierele de date astfelorganizate sunt:

• Crearea în acces secvenţial presupune furnizarea articolelor sortate strict crescător dupăvalorile câmpului ales drept cheie. Articolele sunt scrise cu ajutorul procedurii de scriere în accessecvenţial. Eroarea de cheie invalidă poate apărea la tentativa de scriere a unui articol a cărui cheie estemai mică sau egală decât ultima înscrisă în fişierul de date.

• Crearea în acces direct se realizează cu procedura de scriere în acces direct, articolele fiindfurnizate în orice ordine. Eroarea de cheie invalidă apare la tentativa de scriere a unui articol a căruicheie este egală cu una din cele prezente în fişier.

• Consultarea în acces secvenţial presupune regăsirea articolelor în ordinea strict crescătoare avalorilor cheii. Ea se realizează cu ajutorul procedurii de citire în acces secvenţial, care detectează şisfârşitul fişierului de date.

• Consultarea în acces mixt permite selectarea unui grup de articole, memorate logic contiguuîn fişier, selecţie realizată pe baza valorilor cheii primului şi ultimului articol din grupul dorit. Accesulmixt presupune poziţionarea pe primul articol prin citirea în acces direct (sau poziţionare şi citire înacces secvenţial), urmată de exploatarea în acces secvenţial, până la găsirea cheii ultimului articol dorit,sau până la sfârşitul fişierului.

• Adăugarea de articole se realizează utilizând procedura de scriere în acces direct. Articolelepot fi furnizate în orice ordine a valorilor cheii. Eroarea de cheie invalidă apare la tentativa de scriere aunui articol a cărui cheie este egală cu una deja existentă.

• Modificarea unor câmpuri din articol se realizează în următoarele etape:- citirea articolului de modificat (în acces secvenţial sau direct);- modificarea, în zona articol corespunzătoare, a câmpurilor dorite, cu excepţia câmpului cheie;- rescrierea articolului, cu procedura de rescriere.

Algoritmi şi programe de prelucrare a fişierelorEroarea de cheie invalidă apare în cazul tentativei de rescriere a unui articol a cărui cheie este

diferită de cea a articolului citit anterior.• Ştergerea în acces secvenţial elimină articolul curent din fişierul de date. în general, articolul

trebuie mai întâi identificat printr-o citire (în acces secvenţial sau direct) sau prin poziţionare.Procedura returnează eroare în cazul tentativei de ştergere după ultimul articol existent.

• Ştergerea în acces direct elimină articolul a cărui cheie este precizată. Operaţia nu trebuieprecedată de citirea articolului şi returnează eroare în cazul furnizării unei chei inexistente în fişier. înaplicaţii, este preferabilă ştergerea în acces secvenţial, deoarece permite (datorită citirii care o precede),vizualizarea articolului şi luarea unei decizii în condiţii de siguranţă.

Unitatea Indexate cuprinde o serie de proceduri (primitive), cu rol de instrucţiuni deintrare/ieşire la nivel de fişier şi articol, necesare realizării algoritmilor de prelucrare specificioperaţiilor de gestiune a fişierelor, când se utilizează corespondenţa internă între valorile unui anumitcâmp din articole - numit cheie - şi numerele relative ale acestora. Tabela de corespondenţă între cheişi numerele relative este memorată într-un fişier cu tip, a cărui gestiune este transferată integralprocedurilor aparţinând unităţii, astfel încât programele utilizatorului vor lucra exclusiv cu fişierul dedate. Totuşi, utilizatorul trebuie să ţină cont de existenţa tabelei de indexuri în vederea asigurării spa-ţiului necesar pe disc şi manipulării concomitente a celor două fişiere (salvare, restaurare, ştergere etc.).

În unitate sunt făcute publice următoarele tipuri: TipFis, pentru tipul fişierului de date; TipArt,pentru tipul articolului din fişierul de date; TipCheie, pentru tipul cheii.

Proceduri pentru realizarea operaţiilor de acces la nivel de fişier

♦ Procedura de deschidere a fişierului de date, pentru creare:

OpenNew(VAR f:TipFis; VAR nume:STRING; VAR ivk:BOOLEAN)

F este fişierul de date şi nume este identificatorul său extern. Ivk este indicator de eroare, carereturnează valoarea FALSE, dacă fişierul nu există sau valoarea TRUE, dacă fişierul există deja pedisc. Procedura deschide, pentru creare, fişierul de date (ca fişier nou). Concomitent, se deschide şitabela de indexuri, al cărei nume extern este identic cu al fişierului de date, dar cu extensia .IDX.

Observaţie: la deschiderea tabelei de indexuri ca fişier nou, nu se verifică existenţa acestuia însuport. Fişierul va fi şters şi recreat.

♦♦♦♦ Procedura de deschidere a fişierului de date, pentru consultare şi întreţinere:

OpenOld(VAR f:TipFis; VAR nume:STRING; VAR ivk:BOOLEAN)

F este fişierul de date şi nume este identificatorul său extern. Ivk este indicator de eroare, carereturnează valoarea FALSE, dacă ambele fişiere (de date şi de indexuri) există sau valoarea TRUE,dacă unul din ele nu există. Procedura deschide, pentru consultare, ambele fişiere.

♦♦♦♦ Procedura pentru închiderea fişierului de date:

CloseFile(VAR f:TipFis)

F este fişierul de date. Procedura închide fişierul de date, precum şi tabela de indexuri.

Proceduri pentru realizarea operaţiilor de acces la nivel de articol

♦♦♦♦ Procedura pentru citirea în acces secvenţial a unui articol din fişierul de date:

Algoritmi şi programe de prelucrare a fişierelorReadSeqRec(VAR f:TipFis; VAR z:TipArt; VAR sf:BOOLEAN)

F este fişierul şi z este zona în care se citeşte articolul prezent în fişier. Sf este un indicator desemnalare a atingerii sfârşitului fişierului de date şi are valorile: FALSE, dacă articolul s-a citit (şi nueste sfârşit de fişier) sau TRUE, dacă s-a ajuns la sfârşit de fişier.

Procedura returnează articolul curent din fişierul de date (articolul următor ultimului accesatprintr-o operaţie de intrare/ieşire). Citirea unui articol din fişierul de date se realizează prin intermediultabelei de indexuri. în fapt, se citeşte un articol din tabelă, de la poziţia indicată de pointerul curent şiapoi se citeşte articolul cu numărul relativ y.nr din fişierul de date (y este zona articol a tabelei deindexuri).

Dacă pointerul indică marcatorul de sfârşit al tabelei, parametrul sf va returna valoarea TRUE.Execuţia repetată a acestei proceduri are ca efect furnizarea articolelor din fişierul de date în ordineastrict crescătoare a valorilor cheii.

♦♦♦♦ Procedura pentru citirea în acces direct a unui articol din fişierul de date:

ReadKeyRec(VAR f:TipFis; VAR z:TipArt; Key:TipCheie; VAR ivk:BOOLEAN)

F este fişierul de date şi z este zona articol ataşată lui. Key precizează valoarea cheii articoluluicare se citeşte. Ivk este indicator de eroare, care returnează valoarea FALSE, dacă articolul a fostregăsit sau valoarea TRUE, dacă articolul este absent. Procedura caută, prin procedura Start, cheia cuvaloarea key şi dacă o găseşte, citeşte în z articolul cu numărul relativ y.nr şi face ivk=FALSE; dacănu o găseşte, face ivk:=TRUE.

♦♦♦♦ Procedura pentru scrierea în acces secvenţial a unui articol în fişierul de date:

WriteSeqRec(VAR f:TipFis; VAR z:TipArt; VAR ivk:BOOLEAN)

F este fişierul de date şi z este zona articol ataşată lui. Ivk este indicator de eroare, carereturnează valoarea FALSE, dacă articolul a fost scris, sau valoarea TRUE, în caz contrar. Proceduraadaugă un articol în fişierul de date, concomitent cu extinderea tabelei de indexuri cu o nouăînregistrare, a cărei cheie este mai mare decât cele existente. În cazul în care cheia este mai mică sauegală cu a ultimului articol din tabelă, se returnează eroare (ivk=TRUE) şi articolul nu se scrie.

♦♦♦♦ Procedura pentru scrierea în acces direct a unui articol în fişierul de date:

WriteKeyRec(VAR f:TipFis; VAR z:TipArt; Key:TipCheie;VAR ivk:BOOLEAN)

F este fişierul de date şi z este zona articol ataşată lui. Key precizează valoarea cheii articoluluicare se scrie. Ivk este indicator de eroare, care returnează valoarea FALSE, dacă articolul a fost scrissau valoarea TRUE, în caz contrar.

Procedura adaugă un articol la sfârşitul fişierului de date. Cheia acestuia poate avea oricevaloare, inexistentă în tabela de indexuri. Iniţial, tabela se extinde cu un nou articol şi apoi sereordonează (pentru a satisface cerinţele citirii secvenţiale). în cazul în care cheia furnizată de apelatorse regăseşte în tabelă, articolul nu se scrie şi se returnează eroare de cheie invalidă (ivk=TRUE).Căutarea se face cu procedura Start.

Algoritmi şi programe de prelucrare a fişierelor♦♦♦♦ Procedura pentru rescrierea unui articol în fişierul de date:

RewriteRec(VAR f:Tip VAR z:TipArt; VAR ivk:BOOLEAN)

F este fişierul de date şi z este zona articol ataşată lui. Ivk este indicator de eroare, carereturnează valoarea FALSE, dacă articolul a fost rescris sau valoarea TRUE, în caz contrar.

Procedura transferă datele din z în fişierul de date, în aceeaşi poziţie din care s-a citit anterior(printr-o operaţie de citire în acces secvenţial sau direct). Tabela de indexuri nu se modifică. Proceduraverifică dacă valoarea cheii s-a modificat faţă de momentul citirii sale precedente, caz în care sesemnalează eroare de cheie invalidă (ivk=TRUE).

♦♦♦♦ Procedura pentru ştergerea în acces secvenţial a unui articol:

DeleteSeqRec(VAR f:TipFis; VAR ivk:BOOLEAN)

F este fişierul de date, iar ivk este indicator de eroare, care returnează valoarea FALSE, dacăarticolul a fost şters sau valoarea TRUE, în caz contrar.

Procedura şterge logic articolul curent din fişierul de date. ştergerea se realizează fizic în tabelade indexuri. Iniţial se face y.is=0 şi apoi se elimină articolul din tabelă, prin procedura de sortare.Eroarea de cheie invalidă (ivk=TRUE) este semnalată în cazul în care pointerul curent al tabelei deindexuri indică marcatorul de sfârşit de fişier.

♦♦♦♦ Procedura pentru ştergerea în acces direct a unui articol :

DeleteKeyRec(VAR f:TipFis; Key:TipCheie; VAR ivk:BOOLEAN)

F este fişierul de date şi key precizează valoarea cheii articolului care se şterge. Ivk esteindicator de eroare, care returnează valoarea FALSE, dacă articolul a fost şters sau valoarea TRUE, încaz contrar.

Procedura şterge logic din fişierul de date articolul a cărui cheie este furnizată ca parametru.ştergerea se realizează fizic în tabela de indexuri, analog ştergerii în acces secvenţial. Eroarea de cheieinvalidă (ivk=TRUE) este semnalată în cazul în care articolul respectiv nu se regăseşte în tabelă.Căutarea se face cu procedura Start.

♦ Procedura pentru poziţionare pe un anumit articol din fişierul de date:

Start(VAR f:TipFis; key:TipCheie; VAR ivk:BOOLEAN)

F este fişierul de date şi key precizează valoarea cheii articolului pe care se face poziţionarea.Ivk este indicator de eroare, care returnează valoarea FALSE, dacă articolul există în fişier sauvaloarea TRUE, în caz contrar.

Procedura caută binar cheia cu valoarea key în tabela de indexuri şi dacă:• o găseşte, face ivk=FALSE;• nu o găseşte, face ivk:=TRUE.

Observaţie: Unitatea Indexate include o procedură de sortare (Sort) care nu este publică. Easortează tabela de indexuri şi elimină articolul care are y.is=0.

unit indexate;interfacetype tipcheie= word;

Algoritmi şi programe de prelucrare a fişierelor tipart=record nrm:tipcheie; nume:string[25]; grupa:word; nrd:1..20; nota:array[1..20] of 0..10 end; tipfis=file of tipart;procedure opennew(var f:tipfis; var nume_fis:string; var ivk:boolean);procedure openold(var f:tipfis; var nume_fis:string; var ivk:boolean);procedure closefile(var f:tipfis);procedure readseqrec(var f:tipfis; var z:tipart; var sf:boolean);procedure readkeyrec(var f:tipfis; var z:tipart; key:tipcheie;

var ivk:boolean);procedure writeseqrec(var f:tipfis; var z:tipart; var ivk:boolean);procedure writekeyrec(var f:tipfis; var z:tipart; key:tipcheie;

var ivk:boolean);procedure rewriterec(var f:tipfis; var z:tipart; var ivk:boolean);procedure deleteseqrec(var f:tipfis; var ivk:boolean);procedure deletekeyrec(var f:tipfis; key:tipcheie; var ivk:boolean);procedure start(var f:tipfis; key:tipcheie; var ivk:boolean);implementationtype tipindex=record is:0..1; cheie:tipcheie; nr:word end; tabela=file of tipindex;var g:tabela; y:tipindex;

procedure sort(var g:tabela);var h:tabela; a,b:tipindex; i,j:word;begin assign(h,'temp.dat'); rewrite(h); seek(g,0); for i:=1 to filesize(g) do begin read(g,a); if a.is = 1 then write(h,a); end; close(g); seek(h,0); for i:=1 to filesize(h)-1 do begin seek(h,i-1); read(h,a); for j:=i+1 to filesize(h) do begin seek(h,j-1); read(h,b); if a.cheie > b.cheie then begin

Algoritmi şi programe de prelucrare a fişierelor seek(h,i-1); write(h,b); seek(h,j-1); write(h,a); a:=b end end end; rewrite(g); seek(h,0); for i:=1 to filesize(h) do begin read(h,a); write(g,a) end; close(h); erase(h)end;{...........................................................................................................}procedure opennew;begin assign(f,nume_fis); {$i-} reset(f) {$i+} ; if ioresult <> 0 then begin ivk:=false; rewrite(f); assign(g,copy(nume_fis,1,length(nume_fis)-4)+'.idx'); rewrite(g) end else ivk:=trueend;{...........................................................................................................}

procedure openold;begin assign(f,nume_fis); {$i-} reset(f) {$i+} ; if ioresult = 0 then begin ivk:=false; assign(g,copy(nume_fis,1,length(nume_fis)-4)+'.idx'); {$i-} reset(g) {$i+}; if ioresult <> 0 then ivk:=true end else ivk:=trueend;{...........................................................................................................}procedure closefile;begin close(f); close(g)end;{...........................................................................................................}procedure readseqrec;begin sf:=false; {$i-} read(g,y) {$i+}; if ioresult <> 0 then sf:=true; if not sf then

Algoritmi şi programe de prelucrare a fişierelor begin seek(g,filepos(g)-1);

read(g,y); seek(f,y.nr); read(f,z) endend;{...........................................................................................................}procedure readkeyrec;begin start(f,key,ivk); if not ivk then begin seek(g,filepos(g)-1); read(g,y); seek(f,y.nr); read(f,z) endend;{...........................................................................................................}procedure writeseqrec;begin ivk:=false; if filepos(g) > 0 then begin seek(g,filesize(g)-1); read(g,y); if y.cheie >= z.nrm then ivk:=true end; if not ivk then begin y.is:=1; y.cheie:=z.nrm; y.nr:=filesize(f); write(g,y); seek(f,filesize(f)); write(f,z) endend;{...........................................................................................................}procedure writekeyrec;begin start(f,key,ivk); if ivk then begin y.is:=1; y.cheie:=z.nrm; y.nr:=filesize(f); seek(g,filesize(g)); write(g,y); seek(f,filesize(f)); write(f,z); sort(g); ivk:=false end else ivk:=trueend;{...........................................................................................................}procedure rewriterec;begin start(f,z.nrm,ivk); if not ivk then begin seek(f,filepos(f)-1);

Algoritmi şi programe de prelucrare a fişierelor write(f,z) endend;{...........................................................................................................}procedure deleteseqrec;begin if filepos(g) <= filesize(g) then begin ivk:=false; seek(g,filepos(g)-1); y.is:=0; write(g,y); sort(g) end else ivk:=trueend;{...........................................................................................................}procedure deletekeyrec;begin start(f,key,ivk); if not ivk then deleteseqrec(f,ivk)end;{...........................................................................................................}procedure start;var i,ld,ls:word; vb:boolean;begin ivk:=false; vb:=false; ls:=1; ld:=filesize(g); while not vb and (ld>=ls) do begin i:=(ls+ld) div 2; seek(g,i-1); read(g,y); if y.cheie = key then vb:=true else if y.cheie < key then ls:=i+1 else ld:=i-1; end; if not vb then ivk:=trueend;end.

Exerciţiul 1: Să se realizeze un program pentru crearea în acces direct a unui fişier indexat referitorla situaţia şcolară a studenţilor unei facultăţi, cu articole având următoarea structură:

Note obţinute:Numărmatricol

Nume şiprenume

Grupa Numărdiscipline 1 2 … n

Word String[25] Word 1..20 0..10 0..10 0..10

Cheia este câmpul număr matricol. Datele se introduc de la tastatură, asigurându-se următoarelevalidări:

- câmpul număr matricol: să fie numeric;

Algoritmi şi programe de prelucrare a fişierelor- câmpul nume şi prenume: să fie alfabetic (să fie compus numai din litere mari, litere

mici şi spaţiu);- câmpul grupa: să fie numeric;- câmpul număr discipline: să fie numeric;- câmpurile note obţinute: să fie numerice.În cazul în care valoarea introdusă nu corespunde cerinţelor impuse, se semnalează eroare şi

se reia introducerea. Sfârşitul introducerii datelor se va marca standard (CTRL/Z în câmpul numărmatricol).

Observaţie: Fişierul va fi deschis ca nou, cu primitiva OpenNew. În cazul în care există în directorun fişier cu acelaşi specificator, se semnalează eroare şi se reia introducerea numelui de fişier. Dacănu există, se va crea eticheta fişierului de date cu specificatorul furnizat de către utilizator şi,concomitent, se va crea eticheta fişierului de indexuri.

Scrierea în fişierul indexat se va realiza cu primitiva de scriere în acces direct(WriteKeyRec). Pentru a nu citi inutil, de la tastatură, câmpurile din articol, în cazul în care valoareacheii există deja în tabela de indexuri (eroarea fiind semnalată doar la sfârşitul introduceriiarticolului), s-a optat pentru următoarea variantă:

- se citeşte de la tastatură valoarea cheii (numărul matricol);- se verifică existenţa în fişier a vreunui articol cu aceeaşi valoare a cheii, cu ajutorul

primitivei de poziţionare (Start);- dacă există un astfel de articol, se semnalează eroare şi se reia introducerea valorii

pentru cheie;- dacă nu există articolul, se citesc de la tastatură celelalte câmpuri şi se scrie articolul în

fişier.

program creare_fisier_indexat;uses crt,indexate;var art:tipart; f:tipfis; er,ivk,ivk1:boolean; i,l:byte; s:string[100]; nume_fis:string;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 citire_nrm;begin repeat er:=false; gotoxy(38,5); {$i-}; readln(art.nrm); {$i+}; if ioresult <> 0 then begin s:='Valoare nenumerica !';

Algoritmi şi programe de prelucrare a fişierelor eroare; gotoxy(38,5); clreol end until not erend;(* ------------------------------------- *)procedure citire_nume;begin repeat er:=false; gotoxy(38,6); clreol; readln(art.nume); l:=length(art.nume); for i:=1 to l do if not (art.nume[i] in alfabet) then er:=true; if er then begin s:='Caractere nealfabetice !'; eroare end until not erend;(* ------------------------------------- *)procedure citire_grupa;begin repeat er:=false; gotoxy(38,7); clreol; {$i-}; readln(art.grupa); {$i+}; if ioresult <> 0 then begin s:='Valoare nenumerica !'; eroare; clreol end until not erend;(* ------------------------------------- *)procedure citire_nrd;begin repeat er:=false; gotoxy(38,8); clreol; {$i-} readln(art.nrd); {$i+} if ioresult<>0 then begin s:='Caractere nenumerice !'; eroare end until not erend;(* ------------------------------------- *)procedure citire_note;begin for i:=1 to art.nrd do begin gotoxy(20,i+8);

Algoritmi şi programe de prelucrare a fişierelor write('Nota ',i:2,' : '); repeat er:=false; gotoxy(38,i+8); clreol; {$i-} readln(art.nota[i]); {$i+} if ioresult<>0 then begin s:='Caractere nenumerice !'; eroare end until not er endend;procedure inceput;begin textbackground(blue); textcolor(yellow); clrscr; repeat write('Numele fisierului: '); readln(nume_fis); opennew(f,nume_fis,ivk) until not ivk; clrscr; checkeof:=true; gotoxy(20,5); write('Nr. matricol: '); gotoxy(20,6); write('Nume si prenume: '); gotoxy(20,7); write('Grupa: '); gotoxy(20,8); write('Nr. discipline: '); gotoxy(38,5);end;(* ------------------------------------- *)procedure prelucrare;begin citire_nrm; start(f,art.nrm,ivk); if ivk then begin citire_nume; citire_grupa; citire_nrd; citire_note; writekeyrec(f,art,art.nrm,ivk1); end; if not ivk or ivk1 then begin s:='Articol existent !'; eroare end; for i:=5 to 8 do begin gotoxy(38,i); clreol; end; for i:=9 to 24 do begin gotoxy(20,i); clreol; end; gotoxy(38,5);end;(* ------------------------------------- *)

procedure sfarsit;begin closefile(f);

Algoritmi şi programe de prelucrare a fişierelorend;(* ------------ program principal ----------- *)begin inceput; while not eof do prelucrare; sfarsit;end.

Exerciţiul 2: Să se realizeze programul pentru afişarea informaţiilor existente în fişierul indexatcreat la exerciţiul 1 (nume şi prenume, grupa şi notele obţinute) pentru studenţii ale căror numerematricol se citesc de la tastatură.Observaţii: Fişierul se va deschide pentru consultare, ca fişier existent, cu primitiva OpenOld. Încazul în care nu există un fişier cu specificatorul furnizat de către utilizator, se reia introducereaspecificatorului până când este citit unul valid. Citirea articolului se va realiza în acces direct dupăcheia furnizată, cu ajutorul primitivei ReadKeyRec.

program consultare_acces_direct;uses crt,indexate;var x:tipart; f:tipfis; nrm,i:word; ivk:boolean; nume_fis:string;begin clrscr; repeat write('Numele fisierului: '); readln(nume_fis); openold(f,nume_fis,ivk) until not ivk; clrscr; checkeof:=true; with x do begin gotoxy(10,5); write('Numar matricol:'); while not eof do begin gotoxy(35,5); readln(nrm); readkeyrec(f,x,nrm,ivk); if not ivk then begin gotoxy(15,8); write(nume); gotoxy(10,11); write('Grupa ',grupa); gotoxy(10,13); write('Note obtinute:'); for i:=1 to nrd do begin gotoxy(10,14+i); write('Nota ',i:2,': ',nota[i]:2) end end else begin gotoxy(10,10); write('Articol inexistent !',#7) end;

Algoritmi şi programe de prelucrare a fişierelor readln; clrscr; gotoxy(10,5); write('Numar matricol:') end end; closefile(f)end.Exerciţiul 3: Să se realizeze programul pentru afişarea unor informaţii (număr curent, numărmatricol, nume şi prenume) pentru studenţii din grupele ale căror valori se citesc de la tastatură.Fişierul indexat este cel creat la exerciţiul 1.Observaţii: Programul codifică un algoritm de consultare secvenţială cu selecţie simplă (dupăcâmpul grupa), similar schemei generale de prelucrare – varianta 1 – din figura 1.2, cu o citireiniţială şi o citire curentă, la sfârşitul modulului PRELUCRARE.

Pentru fiecare nouă grupă introdusă de la tastatură, fişierul se parcurge de la primul laultimul articol. De aceea, de fiecare dată, fişierul de date se va deschide (pentru consultare, cuprimitiva OpenOld) înainte de prima citire şi se va închide (cu primitiva CloseFile) după ultimacitire. În cazul în care nu există un fişier cu specificatorul furnizat de către utilizator se va semnalaeroare de sistem şi se va întrerupe execuţia programului.

Citirea articolului se va realiza în acces secvenţial, cu ajutorul primitivei ReadSeqRec.

program consultare_grupa;uses crt,indexate;var x:tipart; f:tipfis; gr,i:word; sf,vb,ivk:boolean; nume_fis:string;begin clrscr; write('Numele fisierului: '); readln(nume_fis); clrscr; checkeof:=true; with x do begin gotoxy(10,1); write('Grupa (sau ^Z):'); while not eof do begin openold(f,nume_fis,ivk); gotoxy(27,1); readln(gr); sf:=false; vb:=false; i:=0; readseqrec(f,x,sf); while not sf do begin if grupa=gr then begin inc(i); gotoxy(10,2+i); write(i:2,'. ',nrm:4,' ',nume); vb:=true end; readseqrec(f,x,sf) end; if not vb then begin gotoxy(25,10); write('Numar grupa eronat !',#7)

Algoritmi şi programe de prelucrare a fişierelor end; readln; clrscr; closefile(f); gotoxy(10,1); write('Grupa (sau ^Z): ') end endend.

Exerciţiul 4: Să se realizeze programul pentru actualizarea fişierului referitor la studenţi, creat laexerciţiul 1.Observaţii:1. Programul oferă utilizatorului funcţiuni de Adăugare, Modificare şi Ştergere, realizate în acces

direct după cheie. În meniul afişat pe ecran există şi funcţia de terminare a programului.2. Funcţia de Adăugare este similară creării, cu deosebirea că verificarea existenţei sau

nonexistenţei articolului în fişier se realizează cu primitiva de citire în acces direct ReadKeyRec.3. Opţiunea de ştergere prevede citirea în acces direct a articolului, afişarea acestuia pe monitor,

confirmarea ştergerii şi, în caz afirmativ, ştergerea în acces secvenţial cu primitivaDeleteSeqRec.

4. Opţiunea de modificare prevede posibilitatea modificării valorii oricărui câmp sau combinaţiede câmpuri. Prin convenţie, tastarea doar lui <ENTER> semnifică nemodificarea câmpuluirespectiv. Modificarea se realizează în următorii paşi: citirea articolului în acces direct,modificarea câmpurilor dorite şi rescrierea articolului cu primitiva RewriteRec.

5. Fiecare funcţiune a programului prevede posibilitatea reluării ei în interior, fără a mai ieşi înmeniul principal. Terminarea unei funcţiuni se realizează prin tastarea caracterului CTRL-Z încâmpul număr matricol (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ă cuprocedura Reset(Input).

program actualizare_fisier_indexat;uses crt,indexate;var f:tipfis; x:tipart; t:text; opt,r:char; ivk:boolean; nrm,i,err:word; aux:string[25]; numefis:string;procedure meniu;begin clrscr; reset(input); gotoxy(30,8); write('Functiunile programului'); gotoxy(36,10); write('1. Adaugare'); gotoxy(36,11); write('2. Modificare'); gotoxy(36,12); write('3. Stergere'); gotoxy(36,13); write('4. Terminare'); gotoxy(30,16); write('Functia aleasa:'); gotoxy(46,16); readln(opt);end;procedure citire_campuri;begin write('Nume si prenume: '); readln(x.nume);

Algoritmi şi programe de prelucrare a fişierelor write('Grupa: '); readln(x.grupa); write('Nr. discipline: '); readln(x.nrd); for i:=1 to x.nrd do begin write('Nota ',i,': '); readln(x.nota[i]) endend;procedure adaugare;begin reset(input); checkeof:=true; clrscr; with x do begin write('Nr. matricol: '); while not eof do begin readln(nrm); readkeyrec(f,x,nrm,ivk); if ivk then begin citire_campuri; writekeyrec(f,x,nrm,ivk) end else writeln('Numarul matricol exista in fisier !'); write('Nr. matricol (sau ^Z): ') end endend;procedure stergere;begin reset(input); checkeof:=true; clrscr; with x do begin write('Nr. matricol: '); while not eof do begin readln(nrm); readkeyrec(f,x,nrm,ivk); if not ivk then begin writeln(nume,' ',grupa); write('Confirmati stergerea ? (d/n): '); readln(r); if upcase(r)='D' then deleteseqrec(f,ivk) end else writeln('Student inexistent in fisier !'); write('Nr. matricol (sau ^Z): ') end endend;

procedure modif_campuri;begin

Algoritmi şi programe de prelucrare a fişierelor with x do begin write('Nume si prenume: ',nume,' '); readln(aux); if aux<>'' then nume:=aux; write('Grupa: ',grupa,' '); readln(aux); if length(aux)<>0 then val(aux,grupa,err); write('Nr. discipline: ',nrd,' '); readln(aux); if aux[0]<>#0 then val(aux,nrd,err); for i:=1 to nrd do begin write('Nota ',i,': ',nota[i],' '); readln(aux); if aux<>'' then val(aux,nota[i],err) end; rewriterec(f,x,ivk) endend;procedure modificare;begin checkeof:=true; clrscr; reset(input); with x do begin write('Nr. matricol: '); while not eof do begin readln(nrm); readkeyrec(f,x,nrm,ivk); if not ivk then modif_campuri else writeln('Student inexistent in fisier !'); write('Nr. matricol (sau ^Z): ') end end;end;{***** Program principal *****}begin clrscr; assign(t,'con'); repeat write('Numele fisierului: '); readln(numefis); openold(f,numefis,ivk) until not ivk; meniu; while opt<>'4' do begin case opt of '1': adaugare; '2': modificare; '3': stergere else begin gotoxy(25,23); write('Functie inexistenta !',#7) end end; meniu endend.