Cap4-fisiere-128.pdf

  • Uploaded by: Ariana Pop
  • 0
  • 0
  • May 2020
  • PDF

This document was uploaded by user and they confirmed that they have the permission to share it. If you are author or own the copyright of this book, please report to us by using this DMCA report form. Report DMCA


Overview

Download & View Cap4-fisiere-128.pdf as PDF for free.

More details

  • Words: 11,183
  • Pages: 59
47

Aplicații

lu cr u

4. 4 Lucru ul cu fișșiere

în

n a memoriei m innterne, de aceeea joacă Fișierelle constituie o extensie nevolatilă un rol importannt în problem mele prelucraare automată a datelor. Înn timp ce fișșierele binarre sînt utilizaate pentru păăstrarea datellor în vedereea prelucrăriii în aplicații,, fișierele textt sînt utilizatte ca rapoartte destinate utilizatorului u sau surse dee date de inttrare pentru diverse apliccații. E posiibilă și o com mbinație a ceelor două roluri: transferuul datelor întrre aplicații caare utilizeazăă modalități diferite de păstrare a dateelor binare (d de exemplu prelucrarea datelor dintrr-o tabelă MS S Excel în caadrul unui prrogram C++)). Exempllele din acesst capitol vorr prezenta urrmătoarele aspecte a ale prelucrării dateelor memoraate în fișiere: • preluarea daatelor de intrrare din fișiere text, m în fișiere f binaree (vectori și matrice), m • prelucrarea masivelor memorate nare de date organizate secvențial, s • prelucrarea fișierelor bin • simularea oorganizării reelative a fișieerelor binare de date, ndexate a fișierelor binaree de date. • simularea oorganizării in Exempllele care urm mează au fostt scrise în mediul m Visuall Studio 20100, dar pot fo și în aalte medii dee programaree C++. fi folosite

În că

4.1. Utiliizarea fișiierelor texxt ca sursse de datee

4.1.1. Fie un fișier text în care c este mem morat un vector cu elem mente reale su ub următoarrea formă: tooate elementtele se află pe același rîndd, separate prin p cîte un spațiu s (fișierrul are un siingur rînd). Scrieți un suubprogram care c preia veectorul din fișier f și îl plassează într-o zonă alocatăă dinamic în memoria innternă, în vedderea prelucrrării ulterioaare. (Se pressupune că maasivul are o dimensiune rezonabilă pentru p a fi înncărcat în mem moria princippală.)

d neecesară vectoorului preluaat, trebuie Pentru a putea alocca memoria dinamică cunnoscută întîi dimensiuneaa lui. O soluțție este efectuuarea unei paarcurgeri sup plimentare a fișierului teext, cu număărarea elemenntelor, urmattă de alocareea memoriei și apoi o nou uă parcurgeree, cu preluareea elementellor și plasarea lor în mem moria internă.. Funcțiaa preluare_veector_1 rezolvă problemaa enunțată mai m sus.

48

Prog gramarea calcullatoarelor

În că

în

lu cr u

// I - numele extern al fisierului i, adresa unde u se va depune d lung gimea mas sivului preluat // E - adresa masivului alocat din namic / NUL LL in caz de e eroare oat* preluare_vector_1 1(char * nu ume, int* n) n flo { float* f v,x; F FILE* f; v v=NULL; nume,"r+"); f fopen_s(&f, ; //f=fopen n(nume,"r"); i if(f) { //determinare numar elemente in i fisier *n=0; ; fscanf_s(f,"%f",&x); while(!feof(f)) { (*n)++; _s(f,"%f",&x x); fscanf_ } entru vecto or //alocare memorie pe if(*n>0) sizeof(floa at)*(*n)); { v=(float*)malloc(s te din fisi ier //preluare element rewind(f); *n=0; _s(f,"%f",&x x); fscanf_ while(!feof(f)) { v[(*n)++]=x; ,&x); fscanf_s(f,"%f", } } fclose(f); } r return v; }

Funcțiia de mai suss este scrisă ținînd cont de d descriereaa teoretică a structurii de datte fișier text și este corecctă chiar dacăă fișierul este gol (rezulttatul va fi NULL L). Totuși, fiișierele text utilizate în practică nu respectă înttotdeauna aceeastă structurră: se poate înntîmpla ca laa sfîrșitul fișiierului text să s nu existe caracterul c EO OF (cod ASCIII 27), care marchează m sffîrșitul fișieruului text, și nici n măcar marcatorul m de sfîrșit s de liniie (perechea CR/LF, coduuri ASCII 133 și 10). Astfel dde fișiere, făără CR/LF duupă ultima valoare, pot fi obținute cu u editoare precum Notepad, Notepad+ ++, MS Visuaal Studio 10, WordPad (ddacă nu se appasă tasta ma valoare) sau create prrin secvențe de program asemănătoarre acesteEntter după ultim ia: f=fopen("test.txt","w" f "); f for(i=1;i<1 0;i++) fprintf(f,"%5.2f ",(float)i); f fclose(f);

49

Aplicații

În cazul c editoruului MS Word d 2010, chiarr dacă nu se apasă tasta Enter E după ultima u valoarre, la salvareea fișierului în format text (cu opțiunnile implicitee) se adaugăă automat perrechea CR/LF F după ultim ma valoare.

lu cr u

Dacă fiișierul din caare se preiauu datele nu conține c măcaar perechea CR/LF C la sfîrrșitul liniei, atunci a funcțiia de mai suss nu o să inccludă ultimuul element în n vectorul connstruit.

p tor_1: Exempluu de utilizaree a funcției preluare_vec

în

float *a; f i int i,l; a a=preluare_ _vector_1("v vector lini ie.txt",&l); i if(!a) //actiuni in cazul esecului e pr reluarii rea unui me esaj //de exemplu, afisar printf("\n\nNu s-a putut p desch hide fisier rul sau nu sint elemen nte"); e else { //prelucrarea vector rului //pentru verificarea a functiei, , poate fi afisat pe ecran e l preluat are a %d elem mente: \n",l); printf("\n\nVectorul for(i=0;i
În că

4.1.2. Fie un fișier text în care c este mem morat un vector cu elem mente reale su ub următoarrea formă: ffiecare element se află pe p un rînd separat s (nu există e rîndurri goale). Scrrieți un subprrogram care preia vectorrul din fișierr și îl plaseazză într-o zon nă alocată dinamic în mem moria internăă, în vederea prelucrării ulterioare. u (S Se presupune că masiî memoria principală.) p vul are o dimennsiune rezonaabilă pentru a fi încărcat în d implemenntare în C++ a funcțiilor care preiau date nuDatorittă modului de merice din fișiere teext (inclusivv stdin), rezollvarea este aceeași ca la exemplul e anterioor, cu aceleaași observațiii privind struuctura fișierrului text din n care se preiau datele. 4.1.3. Fie un fiișier text în care c este meemorată o matrice m cu eleemente reale. Fișierul estee organizat aastfel: pe priimul rînd se află număruul de linii și numărul de coloane, sep parate printr--un spațiu. Pe P fiecare dinn rîndurile următoare u see află elemenntele cîte uneei linii din m matrice, separate prin cîte un spațiu (m matricea este completă - corespunc de dimensiunilo d or din prima linie a fișierrului). Scrieții un subproggram care preeia matriceaa din fișier șii o plasează într-o zonă alocată a dinam mic din mem moria internăă în vederea prelucrării uulterioare. (S Se presupunee că masivul are o dimensiune rezonaabilă pentru a fi încărcat în memoria principală șii că fișierul nu n este gol.)

50

Prog gramarea calcullatoarelor

ma enunțată mai m sus. Funcția ppreluare_maatrice_1 rezoolvă problem

în

lu cr u

// I - numele fisierului i, adresele e unde se depun dimensiunile mat tricei pre eluate // E - adresa matricei alocate a din namic flo oat** preluare_matrice e_1(char* nume, n int* m, int* n) { float f **x; i int i,j; F FILE* f; x x=NULL; f fopen_s(&f, nume,"r+"); ; //f=fopen n(nume,"r"); i if(f) { //preluare dimensiun ni matrice fscanf_s(f,"%d",m); fscanf_s(f,"%d",n); //alocare memorie pe entru matri ice izeof(float t*)*(*m)); x=(float**)malloc(si for(i=0;i<*m;i++) oc(sizeof(f float)*(*n)); x[i]=(float*)mallo //preluare elemente matrice for(i=0;i<*m;i++) for(j=0;j<*n;j++) ,&x[i][j]); ; fscanf_s(f,"%f", fclose(f); } r return x; }

În că

Deoarrece fișierul conține c dimeensiunile exaacte ale matrricei, se pot folosi f bucle cuu număr cun noscut de paași, nefiind nevoie de detectarea d ex xplicită a sfîrșituului de fișierr. Ca urmaree, această fun ncție nu este afectată de aspectele vind sfîrșitull de fișier preezentate la puunctul 4.1.1. priv

Exempllu de utilizarre a funcției ppreluare_maatrice_1:

float **a; f i int l,c,i,j; a a=preluare_ _matrice_1(" "matrice cu u dimensiun ni.txt",&l,& &c); i if(!a) e afi isare mesaj //actiuni in caz de esec, de exemplu tut fi desc chis fisier rul"); printf("\n\nNu a put e else cei preluat te, de exem mplu afisare e pe ecran //prelucrarea matric ce cu %d li inii si %d coloane:\n",l,c); { printf("\n\nMatric for(i=0;i
51

Aplicații

{ for(j=0;j
lu cr u

}

4.1.4. Fie un fiișier text în care c este meemorată o matrice m cu eleemente reale. Fișierul estee organizat aastfel: pe fieccare rînd se aaflă elementtele cîte uneii linii din maatrice, separrate prin cîte un spațiu (m matricea estee completă – toate rînduurile au acelaași număr de elemente). D Dimensiunilee matricei nuu sînt memoorate în fișieer. Scrieți unn subprogram care preiaa matricea diin fișier și o plasează într-o zonă alocată dinamicc din memoria internă îîn vederea prelucrării ultterioare. (See presupune că masivul are o dimennsiune rezonnabilă pentru a fi încărcatt în memoriaa principală.)

În că

în

Pentru a putea alocaa memoria dinamică neceesară matricei, trebuie înntîi determin nate dimensiiunile acesteiia – numărul de linii și numărul n de coloane. c În condițiile c enuunțului, număărul de linii ale a matricei este e egal cu numărul n de rînduri r din fiișier, deci e suuficientă num mărarea rînduurilor din fișșierul text. Deoarece D toatte rîndurile au a același num măr de elemeente – confo orm enunțuluui – este sufiicientă număărarea valorilor de pe oriccare rînd penntru a afla nu umărul de colloane. Deoarece rîndurile sînt s separatee prin perecheea CR/LF, nuumărarea lorr se poate realliza prin citiiri repetate (de ( exemplu cu funcția fgets). f Aceasstă variantă are a dezavanntajul că trebbuie alocat sp pațiu de mem morie suficient pentru texxtul citit. În exemplul e de mai m jos se vaa presupune că c sînt suficiiente 1000 caaractere. Funcțiaa preluare_m matrice_2 rezzolvă cerința problemei, cu restricția anterioară: #de efine MAX 1000 // I - numele fisierului i, adresele e unde se depun dimensiunile mat tricei pre eluate // E - adresa matricei alocate a din namic flo oat** preluare_matrice e_2(char* nume, n int* m, int* n) { float f **x; i int i,j; F FILE* f; c char* rind; x x=NULL; f fopen_s(&f, ; //f=fopen n(nume,"r"); nume,"r+"); i if(f) { //numarare rinduri MAX); rind=(char*)malloc(M fgets(rind,MAX,f); *m=0;

52

Prog gramarea calcullatoarelor

lu cr u

while(!feof(f)) { (*m)++; ; fgets(rind,MAX,f); } d - ultimul l citit //numarare elemente pe un rind i plus 1 //=numarul de spatii j=strlen(rind); *n=1; for(i=0;i<j;i++) if(rind[i]==' ') (*n)++; free(rind); ntru matric ce //alocare spatiu pen izeof(float t*)*(*m)); x=(float**)malloc(si for(i=0;i<*m;i++) oc(sizeof(f float)*(*n)); x[i]=(float*)mallo //preluare elemente matrice rewind(f); for(i=0;i<*m;i++) for(j=0;j<*n;j++) ,&x[i][j]); ; fscanf_s(f,"%f", fclose(f); } r return x;

în

}

Funcțiaa se utilizeazăă la fel ca ceea din exempplul 4.1.3.

În că

narea număruului de linii din d fișier (și implicit a numărului n Deoareece determin de liniii ale matriceei) se bazeazză pe detectaarea sfîrșituluui de fișier, și ș funcția preluarre_matrice_2 2 depinde de structura fizică f a fișieerului prelucrrat. Dacă măcar CR/LF după ultimuul element, attunci ultima linie nu va fi f luată în aceesta nu are m connsiderare, la ffel ca în cazuul exempluluui 4.1.1. 4.1.5. Fie un fișșier text în format f .CSV (valorile de pe fiecare rînd r sînt sepaarate prin caraacterul virguulă), exportaat din MS Excel. E Fiecarre rînd conțiine următoarrele date: num me și prenum me student (m maxim 30 caractere), an nul de studii,, grupa și 200 de note (un nele dintre ele pot fi 0, cu u semnificațiia că în pozițția respectivăă nu există (încă) ( notă. Scrieți un prrogram care preia acestee date și le memorează m înntr-un fișier binar organnizat secvențial în vedereea prelucrărillor ulterioaree – cîte o înreegistrare penntru fiecare student. s Fiecare înregistraarea va avea următoarea structură: Nume N și prenume

An n

Grupa

char[31]

chaar

int

Noote nota 1 charr



ota 20 no char

53

Aplicații

#in nclude #in nclude #in nclude #in nclude

<stdio.h> <string.h> <stdlib.h>

efine MAX 200 #de #de efine NUME1 "Studenti.csv" #de efine NUME2 "Studenti.dat"

lu cr u

F după fiecaare rînd, incluusiv ultiDeoarece MS Excel adaugă auttomat CR/LF mul, nu vor apaare problemeele legate de detectarea sfîrșitului s de fișier prezenntate mai sus. Programul care rezolvăă cerința este următorul:

în

voi id main () { FILE F *f, *g; t typedef struct{ char nume[31]; n char an; a int gr rupa; char note[20]; n } STUDEN NT; S STUDENT x; c char rind[200]; c char mc[23][31]; i int n,i,j,k;

În că

fopen_s(&f,NUME1,"r"); f ; i if(!f) l %s nu poa ate fi deschis",NUME1); printf("\n\nFisierul e else { fopen_s(& &g,NUME2,"wb b"); if(!g) printf("\n\nFisier rul %s nu poate p fi de eschis",NUME2); else { //preluarea primul lui rind di in fisierul l text ; fgets(rind,MAX,f); eluat un ri ind //cit timp s-a pre while(!feof(f)) { n=strlen(rind); nte din lin nia curenta, //separare cuvin e cuvinte mc, m 1 pe li inie //in vectorul de i=j=0; ) for(k=0;k
} fclose(f);

lu cr u

} triculare (sau ( CTRL+Z Z): "); printf("\nNr inmat fflush(stdin); gets(nr);

} p printf("\nG ; ata, apasa o tasta"); _ _getch(); }

4.3.7. Fie un fişşier organizaat secvenţial, cu articole de d următoareea structură: Grupăă

Nr. discipline

int

char

în

Nr.. matri- Numee și prenume An col student int c char[30] char

Note obţinutee: 1 2 … 20 char cchar char char

Să se sccrie program mul C pentru realizarea unnei liste cu studenţilor s in ntegralişti (înttr-un fișier teext).

În că

#in nclude <stdio.h> #in nclude

pedef struct { int nrm mat; typ char nu ume[30]; char an n; int gru upa; char nr rd; char no ote[20]; } STUDENT T; id main() voi { FILE F *f,*g; S STUDENT x; c char nume_f[20]; i int nr,i,restante;

printf("\nNume fisier: "); p g gets(nume_f );

73

Aplicații

în

lu cr u

fopen_s(&f,nume_f,"rb" f "); i if(!f) % nu poate e fi deschi is"); printf("\nFisierul %s e else { fopen_s(& &g,"Lista.tx xt","w"); fprintf(g,"Lista stu udentilor integralist i ti\n\n"); fprintf(g,"\n Nr. %-30s An Gru upa Note","Nume"); nr=0; DENT),1,f); ; fread(&x,sizeof(STUD while(!feof(f)) { restante=0; ++) for(i=0;i<x.nrd;i+ if(x.note[i]<5) restante=1; if(!restante) { nr++; d %-30s %2d d %5d ",nr,x.nume,x.an,x.grupa); ; fprintf(g,"\n%4d ;i++) for(i=0;i<x.nrd; te[i]); fprintf(g,"%5.2f ",x.not } &x,sizeof(ST TUDENT),1,f f); fread(& } if(!nr) ista nici un u student integralist t"); printf("\n\nNu exi else n fisierul Lista.txt"); printf("\n\nLista se afla in fclose(g); fclose(f); } p printf("\nG ; ata, apasa o tasta"); _ _getch();

În că

}

4.3.8. Fie un fişşier organizaat secvenţial, cu articole de d următoareea structură: Nr. N înmatriculare char[8]

Maarca charr[20]

An fabricaţie int

Nr. km long

Valloare float

Să se realizeze proogramul C pentru listareaa într-un fişier text a autooturismelor mai vechi dee 10 ani şi cuu peste 3000000 km.

#in nclude <stdio.h> #in nclude

pedef struct { char nr rm[8]; typ char ma arca[20]; int anf f;

74

Programarea calculatoarelor

void main() { FILE *f,*g; VEHICUL x; int an,ani,nr; long km; char nume_f[20];

lu cr u

long km; float val; } VEHICUL;

în

printf("\nNume fisier: "); gets(nume_f); fopen_s(&f,nume_f,"rb"); if(!f) printf("\nFisierul %s nu poate fi deschis"); else { fopen_s(&g,"Lista.txt","w"); printf("\nAnul curent: "); scanf("%d",&an); //anul curent poate fi preluat si automat din data calculatorului printf("\nLimita nr. kilometri: "); scanf("%d",&km); printf("\nVechime minima (ani): "); scanf("%d",&ani);

În că

fprintf(g,"Lista vehiculelor mai vechi de %d ani si cu mai mult de %d kilometri\n\n",ani,km); fprintf(g,"\n Nr. %-20s An Km Valoare","Marca"); nr=0; fread(&x,sizeof(VEHICUL),1,f); while(!feof(f)) { if((an-x.anf>ani) && (x.km>km)) { nr++; fprintf(g,"\n%4d %-20s %4d %6d %10.2f",nr,x.marca,x.anf,x.km,x.val); } fread(&x,sizeof(VEHICUL),1,f); } if(!nr) printf("\nNici un vehicul nu indeplineste conditiile date"); else printf("\nLista se afla in fisierul Lista.txt"); fclose(g); fclose(f); } printf("\nGata, apasa o tasta"); _getch(); }

75

Aplicații

Temee 1. Pentru toate fișierele organizate secvențial descrise mai suus, scrieți progrrame multifuuncționale caare realizeazză toate opeerațiunile de gestiune necesarre.

lu cr u

4.4. Simu ularea organizării relative a fișiereloor binare p d gestiune a fișierelor binare de b de datte organiPentru rrezolvarea problemelor zatee relativ fie sse implemenntează pas cu pas operațiile de gestiunne de bază (o ori de cîte ori e nevoie), fie se scriu funcții caree simulează operațiile de d gestiune de bază, ascunzînd gestiiunea indicattorului de staare în interioorul lor. Acesste funcții auu un grad de generalitate ridicat; nefiiind legate dee structura arrticolelor fișiierelor prelucrate, ele pot fi utilizate ppentru orice problemă p de acest tip. În continuare se prrezintă un exxemplu de im mplementaree a acestor operațiuni o n subprogram me. prin

În că

în

Relative.cpp conține funccțiile care im mplementeazăă operațiunille de gesFișierul R tiun ne de bază pentru fișierele organizatee relativ. Inddicatorul de stare s este adăăugat autom mat articoleloor logice, obțținînd articollele fizice alee fișierului. Indicatorul I de stare se aflăă în primul ooctet al artico olelor fizice.. Deoarece inndicatorul dee stare rămîn ne ascuns în interiorul i funncțiilor, proggramul care le utilizeazăă trebuie să declare d și să utilizeze doaar structura ccorespunzătoare articoluluui logic. Se pressupune că fișșierele cu carre se lucreazză în exemplele următoarre au fost creaate folosind aceste funcțiii (adică au aceeași a structtură fizică a articolelor, cu c indicatoru ul de stare înn primul octtet); această limitare a grradului de geeneralitate al subprogramelor este uun compromis acceptabil. #in nclude <stdio.h> #in nclude <malloc.h> #in nclude <string.h>

n fisier (n nr. articol le fizice) // numar total spatii in iunea unui articol lo ogic // I - fisierul, dimensi ice (-1 dac ca fisierul l nu e deschis) // E - nr. articole fizi t NrSpatii(FILE* f, lo ong dim) int { long l p; i int nr; n nr=-1; i if(f) { p=ftell(f); ; fseek(f,0,SEEK_END); ; nr=ftell(f)/(dim+1); ; fseek(f,p,SEEK_SET); }

76

Programarea calculatoarelor

return nr; }

lu cr u

// pozitia curenta in fisier // I - fisierul, dimensiunea unui articol logic // E - pozitia curenta, in nr. de articole, -1 daca fisierul e inchis int Pozitia(FILE* f, long dim) { int nr; nr=-1; if(f) nr=ftell(f)/(dim+1); return nr; }

În că

în

// preformare fisier // I - fisierul, dim. art., nr. art. pentru preformare/extindere // E - cod eroare: 0 - succes, 1 - fisierul era inchis int Preformare(FILE* f, long dim, int nr) { int i,er; char *art; er=1; if(f) { fseek(f,0,SEEK_END); art=(char*)malloc(dim+1); art[0]=0; for(i=0;i
// pozitionare // I - fisierul, dim. art., pozitia dorita in nr. relativ articol // E - cod eroare, 0 - succes, 1 - pozitia prea mare, 2 – fis. inchis int Pozitionare(FILE* f, long dim, int p) { int er; er=2; if(f) if(p
77

Aplicații

lu cr u

// I - fisierul, dim. art., adresa la care se depune articolul citit // E - cod eroare, 0 – art. citit, 1 – fis. inchis, 2 - sfirsit fisier int CitesteUrmatorul(FILE* f, long dim, void* adresa) { char* art; int er=1; if(f) { art=(char*)malloc(dim+1); fread(art,dim+1,1,f); while((!feof(f)) && (er==1)) { if(art[0]) { er=0; memcpy(adresa,art+1,dim); } else fread(art,dim+1,1,f); } if(er==1) er=2; free(art); } return er; }

În că

în

// citire in acces direct // I - fisierul, dim. art., cheia art., adresa unde se depune articolul // E - cod eroare, 0 – art. citit, 1 – fis. inchis sau poz. prea mare, // 2 - cheie invalida int CitestePozitia(FILE* f, long dim, int poz, void* adresa) { char* art; int er; er=Pozitionare(f, dim, poz); if(!er) { art=(char*)malloc(dim+1); fread(art,dim+1,1,f); if(art[0]==0) er=2; else { er=0; memcpy(adresa, art+1, dim); } free(art); } return er; } // scriere articol in acces direct // I - fisierul, dim. art., adresa articolului, cheia articolului // E - cod eroare, 0 - succes, 1 – fis. inchis, 2 - cheie invalida int ScriePozitia(FILE* f, long dim, void* adresa, int poz) { char* art; int n,er=1;

78

Programarea calculatoarelor

lu cr u

if(f) { n=NrSpatii(f,dim); if(poz>=n) Preformare(f,dim,poz-n+1); art=(char*)malloc(dim+1); Pozitionare(f,dim,poz); fread(art,dim+1,1,f); if(art[0]==1) er=2; else { er=0; memcpy(art+1,adresa,dim); art[0]=1; Pozitionare(f,dim,poz); fwrite(art,dim+1,1,f); } free(art); } return er; }

în

// suprascriere articol in vederea modificarii, in acces direct // I - fisierul, dim. art., adresa articolului, cheia articolului // E - cod eroare: 0 - succes, 1 – fis. inchis, 2 - pozitia e prea mare int RescriePozitia(FILE* f, long dim, void* adresa, int poz) { char* art; int n,er=1;

În că

if(f) { n=NrSpatii(f,dim); if(poz>=n) er=2; else { art=(char*)malloc(dim+1); Pozitionare(f,dim,poz); er=0; memcpy(art+1,adresa,dim); fwrite(art,dim+1,1,f); } free(art); } return er;

}

// sterge articolul cu cheia data // I - fisierul, dimensiunea unui articol, cheia articolului de sters // E - cod eroare, 0 - succes, 1 – fis. inchis sau pozitie prea mare, // 2 - cheie invalida (spatiu gol), int Sterge(FILE*f, long dim, int poz)

79 { c char* art; i int er; e er=Pozition are(f,dim,p poz); i if(!er) { art=(char*)malloc(di im+1); ); fread(art,dim+1,1,f) if(art[0]==0) er=2; else { er=0; art[0]=0; ,poz); Pozitionare(f,dim, 1,f); fwrite(art,dim+1,1 } free(art); } r return er; }

lu cr u

Aplicații

4.4.1. Fie un fişşier organizaat relativ, cu date despre colaboratoriii unei societăăţi de colecttare a materiialelor refolo osibile. Fiecaare colaborato or predă un ssingur tip dee material refo olosibil. Dateele se referă la un an callendaristic. Articolele A au următoarea structură logică: Cantitaate predată lunnar 5 6 7 8 9 int int int intt int

în

Tip Num me/denumire material m coolaborator 1 char c char [20] i int

2 int

3 int

4 int

10 int

11 int

12 int

În că

Cheia rellativă a fişierrului este coddul colaboratorului. Să se scrrie programuul C pentru adăugarea de noi articole în fişier. Sfî fîrşitul introd ducerii dateloor de la tastaatură este maarcat standardd.

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

pedef struct { char ti ipm; typ char nume[20]; int cant[12]; c } COLAB BORATOR; id main() voi { FILE* F f; C COLABORATOR x; u unsigned int codc; i int i,er,n;

80

Prog gramarea calcullatoarelor

long dim; l c char nume_f[20]; COLABORATOR d dim=sizeof( R);

În că

în

lu cr u

printf("\nNume fisier colaborato p ori: "); _f); g gets_s(nume i if(fopen_s( "wb+")) &f,nume_f," % nu a put tut fi deschis", nume_ _f); printf("\nFisierul %s e else { printf_s("\nCod cola aborator no ou: "); ; scanf_s("%d",&codc); while(!feof(stdin)) c,&x); { er=CitestePozitia(f,dim,codc if(er==2) a de eja altui co olaborator" "); printf("\nCodul introdus apartine else denumire co olaborator: "); { printf("\nNume/d fflush(stdin); gets(x.nume); erial (H/S/ /A/F): "); printf("Tip mate ipm); scanf("%c",&x.ti if(x.tipm<'a') +'a'-'A'; x.tipm=x.tipm+ tile se ini itializeaza cu 0"); printf("Cantitat +) for(i=0;i<12;i++ x.cant[i]=0; dim,&x,codc c); ScriePozitia(f,d } _s("\n\nCod colaborato or nou: "); printf_ scanf_s("%d",&codc c); } fclose(f); } p printf("\nA Apasa o tast ta!"); _ _getch();

}

4.4.2. Fie fișierrul descris în n exercițiul anterior. a Să se scrie progrramul C penntru afişarea colaboratoruului (colaborratorilor) carre au predat cantități anuuale maximee dintr-un material refolosibil (introodus de la taastatură). Se vor preciza cod, nuanuumit tip de m me//denumire şi cantitate tottală.

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

81

Aplicații

void main() { FILE* f; COLABORATOR x; unsigned int codc; int er,n; long dim; char nume_f[20],mat; int cod_max[50],nr,max,s,i; dim=sizeof(COLABORATOR);

lu cr u

typedef struct { char tipm; char nume[20]; int cant[12]; } COLABORATOR;

În că

în

printf("\nNume fisier colaboratori: "); gets_s(nume_f); if(fopen_s(&f,nume_f,"rb+")) printf("\nFisierul %s nu a putut fi deschis", nume_f); else { nr=0; max=0; printf("Tip material (H/S/A/F): "); scanf("%c",&mat); if(mat<'a') mat=mat+'a'-'A'; er=CitesteUrmatorul(f,dim,&x); while(!er) { if(x.tipm==mat) { s=0; for(i=0;i<12;i++) s+=x.cant[i]; if(s>max) { nr=1; max=s; cod_max[0]=Pozitia(f,dim)-1; } else if(s==max) cod_max[nr++]=Pozitia(f,dim)-1; } er=CitesteUrmatorul(f,dim,&x); } printf("\nCantitatea maxima anual de <%c> este %d si a fost primita de la\n"); for(i=0;i
82

Prog gramarea calcullatoarelor

fclose(f); } p printf("\nA Apasa o tast ta!"); _ _getch(); }

Nume clientt char [30]

lu cr u

4.4.3. Fie un fişşier organizaat relativ, cu date despre facturile em mise de o sociietate comerrcială. Articoolele au urmăătoarea strucctură logică: Dataa facturării zi luna an char char int

Nr. produse intt

Valoare prooduse 1 2 … 50 flooat float float

Cheia relativă a fişierului este numărul factuurii. Să se sccrie program mul C pentru listarea într--un fişier text a facturilorr din anul treccut a căror valoare depăşşeşte o limităă dată. Se voor preciza nuumăr factură,, client şi valooare.

în

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

În că

pedef struct { char nu ume[30]; typ char zi i; char lu una; int an; ; int nr; ; int val l[50]; } FACTURA A; id main() voi { FILE* F f,*g; F FACTURA x; l long dim; c char nume_f[20]; i int codf,val_lim,an,er r,s,i; d dim=sizeof( FACTURA);

printf("\nNume fisier: "); p g gets(nume_f ); e er=fopen_s( "rb"); &f,nume_f," i if(er) te deschide e fisierul %s",nume_f); printf("\nNu se poat e else { printf("\nNume fisie er lista: "); "

83

Aplicații

lu cr u

fflush(stdin); gets(nume_f); &g,nume_f,"w w"); fopen_s(& printf("\nAnul cauta at: "); scanf("%d",&an); inima: "); printf("\nValoare mi scanf("%d",&val_lim) ); cturilor cu u valoarea mai mare de ecit %d din n anul fprintf(g,"Lista fac \n\n",val_lim,an); %d\ fprintf(g,"\nNr.fact t %-30s Val loare","Num me / denumire client") ); er=CitesteUrmatorul(f,dim,&x); ; while(!er) { if(x.an==an) { s=0; for(i=0;i<x.nr;i i++) s+=x.val[i]; if(s>=val_lim) %7d %-30s %6d",Poziti % ia(f,dim)-1,x.nume,s); ; fprintf(g,"\n% } ul(f,dim,&x x); er=CitesteUrmatoru } fclose(f); fclose(g); a in fis sierul %s",nume_f); printf("\nLista se afla

în

} p printf("\nA Apasa o tast ta!"); _ _getch(); }

4.4.4. Fie un fişşier organizaat relativ, cu articole a avînnd următoareaa structură lo ogică:

În că

Denumire produs char[30]

U.M.

Preţ P unitar

char[5]

float

1 int

Caantităţi vîndutte lunar: 2 … int

12 int

Codul produsului p inndică număruul relativ al articolului a în fişier. Să se sccrie program mul C pentru ştergerea prooduselor ale căror codurii se introducc de la tastatuură. Sfîrşitul introducerii datelor de laa tastatură esste marcat staandard.

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

pedef struct { char de enumire[30] ]; typ char um m[5]; float pretu; p

84

Programarea calculatoarelor

void main() { FILE* f,*g; PRODUS x; long dim; char nume_f[20],r; int codp,er; dim=sizeof(PRODUS);

lu cr u

int cant[12]; } PRODUS;

În că

în

printf("\nNume fisier: "); gets(nume_f); er=fopen_s(&f,nume_f,"rb"); if(er) printf("\nNu se poate deschide fisierul %s",nume_f); else { printf("\Cod produs: "); scanf("%d",&codp); while(!feof(f)) { er=CitestePozitia(f,dim,codp,&x); if(er) printf("\nCodul %d nu crespunde unui produs",codp); else { printf("\nCodul %d corespunde produsului:\n",codp); printf("\nDenumire: %s, unitate de masura: %s, pret unitar: %8.2f",x.denumire,x.um,x.pretu); printf("\nConfirmati stergerea? (D/N): "); r=_getche(); if(r!='D') printf("\nStergere abandonata"); else { Sterge(f,dim,codp); printf("\nProdusul cu codul %d a fost sters",codp); } } printf("\nCod produs: "); scanf("%d",&codp); } fclose(f); } printf("\nApasa o tasta!"); _getch(); }

4.4.5. Fie un fişier organizat relativ, cu articole avînd următoarea structură logică: Denumire fond fix

Tip fond fix

Data achiziţiei an lună zi

Valoare inventar

Gestionar

85

Aplicații

char[30]

char[220]

int

char

chaar

float

char[3 30]

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

lu cr u

Număruul de inventaar indică num mărul relativ al articoluluii în fişier. Să se sccrie program mul C pentruu afişarea fonndurilor fixee ale căror nuumere de inventar se introoduc de la taastatură. Sfîrşşitul introduccerii datelor eeste marcat standard. s

pedef struct { char de enumire[30] ]; typ char ti ip[20]; int an; ; char lu una; char zi i; float val_inv; v char ge est[30]; } FOND_FI IX;

în

id main() voi { FILE* F f,*g; F FOND_FIX x; l long dim; c char nume_f[20]; i int nri,er;

d dim=sizeof( FOND_FIX);

În că

printf("\nNume fisier: "); p ); g gets(nume_f e er=fopen_s( "rb"); &f,nume_f," i if(er) printf("\nNu se poat te deschide e fisierul %s",nume_f); e else { printf("\Numar inven ntar: "); scanf("%d",&nri); while(!feof(f)) ,&x); { er=CitestePozitia(f,dim,nri, if(er) l de invent tar %d nu crespunde unui fond printf("\Numarul x",nri); fix else l de invent tar %d core espunde fond dului { printf("\Numarul x:\n",nri); fix ire: %s \nT Tip: %s \ndata achizit tiei: printf("\nDenumi %d.%d.%d",x.denumire,x.t tip,x.zi,x. .luna,x.an); re inventar r: %8.2f",x x.val_inv); printf("\nValoar

86

Prog gramarea calcullatoarelor

printf("\nGestio onar: %s",x x.gest); } nventar: ") ); printf("\nNumar in scanf("%d",&nri);

} p printf("\nA Apasa o tast ta!"); _ _getch(); }

lu cr u

} fclose(f);

4.4.6. Fie un fişşier organizaat relativ, cu articole a de următoarea sttructură: Nume şi prenum me

An de studiu

char [30]

chaar

Grrupa

Nr. discipline

innt

char

Note obţiinute 1 2 … 15 char char char

în

Număruul matricol inndică număruul relativ al articolului a înn fişier. Scrieţi uun program C pentru însscrierea interractivă în fişşier a notelorr obţinute în urma u susţineerii unor exaamene. Fiecaare materie are a asociată o anumită poziție p în vecctorul de notee. Sfîrşitul inntroducerii daatelor este marcat m standarrd.

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

În că

pedef struct { char nu ume[30]; typ char an n; int gru upa; char nr rd; char no ote[15]; } STUDENT T; id main() voi { FILE* F f; S STUDENT x; l long dim; c char nume_f[20]; i int nrm,er,i,n;

d dim=sizeof( STUDENT);

printf("\nNume fisier: "); p g gets(nume_f ); e er=fopen_s( "rb"); &f,nume_f," i if(er) printf("\nNu se poat te deschide e fisierul %s",nume_f);

87

Aplicații

}

în

lu cr u

else e { printf("\Numar matri icol: "); scanf("%d",&nrm); while(!feof(f)) ,&x); { er=CitestePozitia(f,dim,nrm, if(er) l matricol %d nu crespunde unui student",n nrm); printf("\Numarul else l matricol %d corespu unde student tului:\n",n nrm); { printf("\Numarul me); printf("\nNume: %s ",x.num d Grupa: ", ,x.an,x.gru upa); printf("\nAn: %d m (1-%d): ",x.n nrd); printf("Indice materie scanf("%d",&i); printf("\nNota: "); scanf("%d",&n); x.note[i]=n; f,dim,&x,nr rm); RescriePozitia(f } atricol: ") ); printf("\nNumar ma scanf("%d",&nrm); } fclose(f); } p printf("\nA Apasa o tast ta!"); _ _getch();

În că

4.4.7. Fie fișierrul descris în n exercițiul anterior. a Scrieți un prograam C pentru exmatrim de 5 resttanțe. culaarea studențiilor cu mai mult

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

pedef struct { char nu ume[30]; typ char an n; int gru upa; char nr rd; char no ote[15]; } STUDENT T; id main() voi { FILE* F f; S STUDENT x; l long dim; c char nume_f[20]; i int nrm,er,i,n;

88

Prog gramarea calcullatoarelor

d dim=sizeof( STUDENT);

lu cr u

printf("\nNume fisier: "); p ); g gets(nume_f &f,nume_f," e er=fopen_s( "rb"); i if(er) te deschide e fisierul %s",nume_f); printf("\nNu se poat e else { er=CitesteUrmatorul(f,dim,&x); ; while(!er) { n=0; ++) for(i=0;i<x.nrd;i+ if(x.note[i]<5) n++; if(n>5) zitia(f,dim m)-1); Sterge(f,dim,Poz ul(f,dim,&x x); er=CitesteUrmatoru } ea s-a inch heiat"); printf("\nPrelucrare fclose(f); } p printf("\nA Apasa o tast ta!"); _ _getch();

în

}

În că

4.4.8. Fie fișierrul descris în n exercițiul 4.4.6. Scrieți un u program C pentru mo odificarea uprins înanuului de studiuu (se va trecee anul 1) penntru studențiii cu număruul matricol cu tre două valori date de la tastatură (a, b)). Se presupu une că existăă un student cu c numărul matricol a.

#in nclude <stdio.h> #in nclude #in nclude "Relative.cpp"

pedef struct { char nu ume[30]; typ char an n; int gru upa; char nr rd; char no ote[15]; } STUDENT T; voi id main() { FILE* F f; S STUDENT x; l long dim; c char nume_f[20];

89

Aplicații

i int nrm,er,a,b; d dim=sizeof( STUDENT);

}

în

lu cr u

printf("\nNume fisier: "); p g gets(nume_f ); e er=fopen_s( "rb"); &f,nume_f," i if(er) te deschide e fisierul %s",nume_f); printf("\nNu se poat e else { printf("\nPrimul num mar matrico ol: "); scanf("%d",&a); ,dim,a,&x); ; er=CitestePozitia(f, if(er) % nu corespunde unui student",a a); printf("\nNumarul matricol %d else itia(f,dim) )<=b+1)) { while((!er)&&(Pozi { x.an=1; f,dim,&x,Po ozitia(f,di im)-1); RescriePozitia(f orul(f,dim, ,&x); er=CitesteUrmato } } ea s-a inch heiat"); printf("\nPrelucrare fclose(f); } p printf("\nA Apasa o tast ta!"); _ _getch();

În că

Temee 1. Se observ vă că toate funcțiile fu impllementate mai m sus pentru u simularea opperațiunilor de gestiune de bază folo osesc ca paraametri fișier și ș dimensiune aarticol logic. Se poate evvita transmitterea lor expplicită, dacă funcțiile respectiive au accees direct laa aceste varriabile. Resccrieți acestee funcții, incluzînndu-le împreeună cu cele două variabbile într-o strructură de date unică (struct)). 2. Pentru ttoate fișierelle relative deescrise mai su us, scrieți prrograme multtifuncționale carre realizeazăă toate operațțiunile de gesstiune necesaare.

4.5. Simu ularea organizării indexate a fișierelor binaree

mătoarea prooblemă: în cadrul c unei organizații o d învățămînnt trebuie de Fie urm gesstionate urmăătoarele datee referitoare la studenți: cod matricool, nume și prenume, p gru upa de studiuu, anul de stuudiu, note obbținute (maxxim 20). Se dorește ca accesul a la datee să se facă prin intermeediul coduluui matricol, care c este o seecvență alfan numerică de 10 caractere – acesta va constitui c cheeia indexată. Se cere să see scrie progrrame care

90

Prog gramarea calcullatoarelor

să realizeze r urm mătoarele op perațiuni de gestiune: g poppularea inițiaală a fișierullui, adăugarrea de noi stuudenți, vizuaalizarea datellor despre unn student, vizzualizarea daatelor despree studenții uunei grupe, înscrierea î unnei note penttru un studeent, înscrierea notelor penntru o grupă de studenți, eliminarea unui studennt (exmatricuulare, absolvvire etc.). Pen ntru toate opeerațiile datelle se preiau de d la tastatură și se asigurră repetarea prelucrării pînă p la apăsaarea combinaației de taste CTRL-Z.

lu cr u

Pentru a simplifica gestiunea fișșierelor organnizate indexaat se pot realliza funcții care c implem mentează operrațiile de gesstiune de bazză. Acestea vor v fi utilizaate pentru imp plementarea operațiilor enunțate e maii sus. În exeemplul urmăător este prezzentată o modalitate de im mplementaree a acestor opperații.

Fișierul Tipuri.h connține declarațțiile tipurilorr de date utiilizate atît peentru immentarea operațiilor de bază b cît și pentru rezolvarrea problemeelor enunțatee. plem //t tipul fisier #de efine TFISIER FILE* tipul cheii //t typ pedef char TCHEIE[11]; ;

în

//t tipul articol din tabe ela index typ pedef struct{ char is; ; TCHEIE cheie; c long nr_ _rel; } TART_IND DEX;

În că

tipul articol din fisi ierul de da ate //t typ pedef struct{ TCHEIE cheie; c char num me[35]; int grup pa; int an; e[20]; int note } TARTICOL L;

Fișierul IIndexat.cpp conține funccții care impllementează operațiile o dee gestiune b pentru fișierul orgaanizat indexaat și variabilee asociate unnui fișier orgaanizat inde bază dexxat: fișierul dde date, tabeela index, unn articol, num mele extern al a fișierului organizat o indexat (fără exxtensie) – din n acesta se obțin o numelee celor două fișiere fizicee (de date și in ndex) prin addăugarea exttensiilor resppective. #in nclude <stdio.h> #in nclude <string.h> #in nclude "tipuri.cpp"

91

Aplicații

TARTICOL x; char nume[20],numed[20],numei[20]; TFISIER f; TFISIER ind;

lu cr u

// Extindere nume prin adaugarea extensiilor void Extinde() { strcpy(numei,nume); strcat(numei,".idx"); strcpy(numed,nume); strcat(numed,".dat"); }

// Sortarea tabelei index si eliminarea inregistrarilor sterse // I // E void Sort() { TART_INDEX a,b; TFISIER ind1; long i,j;

în

//copierea tabelei index intr-un fisier temporar (numai art. valide) ind1=fopen("temp.idx","wb+"); rewind(ind); fread(&a,sizeof(a),1,ind); while(!feof(ind)) { if(a.is) fwrite(&a,sizeof(a),1,ind1); fread(&a,sizeof(a),1,ind); } fclose(ind);

În că

//sortarea fisierului temporar fseek(ind1,0,SEEK_END); long n=ftell(ind1)/sizeof(a); for(i=0;i0) { fseek(ind1,i*sizeof(a),SEEK_SET); fwrite(&b,sizeof(a),1,ind1); fseek(ind1,j*sizeof(a),SEEK_SET); fwrite(&a,sizeof(a),1,ind1); } } } fclose(ind1);

92

Programarea calculatoarelor

//inlocuirea tabelei index cu fisierul sortat remove(numei); rename("temp.idx",numei); ind=fopen(numei,"rb+"); }

În că

în

lu cr u

/* Cautarea articolului cu cheia Key si plasarea pointerului de fisier in tabela de indexuri pe articolul respectiv*/ // I - cheia cautata // E - cod succes: 1 - a fost gasit articolul; 0 - nu a fost gasit articolul int SeekKey(char *Key) { long ls=0, ld, m, n; TART_INDEX a; int gasit=0; fseek(ind,0,SEEK_END); n=ftell(ind)/sizeof(TART_INDEX); ld=n-1; while((ls<=ld)&&(!gasit)) { m=(ls+ld)/2; fseek(ind,m*sizeof(a),SEEK_SET); fread(&a,sizeof(a),1,ind); if(strcmp(a.cheie,Key)==0) gasit=1; else if(strcmp(a.cheie,Key)>0) ld=m-1; else ls=m+1; } if(gasit) fseek(ind,m*sizeof(a),SEEK_SET); return gasit; } // Crearea unui fisier indexat nou // I // E void New_index() { f=fopen(numed,"wb+"); ind=fopen(numei,"wb+"); } // Deschiderea unui fisier indexat existent // I // E void Open_index() { f=fopen(numed,"rb+"); ind=fopen(numei,"rb+"); }

93

Aplicații

lu cr u

// Inchiderea tabelei index // I // E void Close_index() { fclose(ind); fclose(f); }

în

// Citirea urmatorului articol in acces secvential // I - adresa unde se depune articolul citit // E - cod de succes: 1 - a fost citit; 0 - nu a fost gasit nici un articol int ReadSec(TARTICOL *a) { TART_INDEX a1; int r; fread(&a1,sizeof(a1),1,ind); if(feof(ind)) r=0; else { fseek(f,a1.nr_rel*sizeof(*a),SEEK_SET); fread(a,sizeof(*a),1,f); r=1; } return r; }

În că

// Citirea articolului cu o cheie data, in acces direct // I - adresa unde se depune articolul citit, cheia articolului cautat // E - cod de succes: 1 - a fost citit; 0 - nu a fost gasit nici un articol int ReadKey(TARTICOL *a,char *Key) { TART_INDEX a1; int r; if(SeekKey(Key)) { fread(&a1,sizeof(a1),1,ind); fseek(f,a1.nr_rel*sizeof(*a),SEEK_SET); fread(a,sizeof(*a),1,f); r=1; } else r=0; return r; } // Scrierea unui articol in acces secvential // I - articolul care trebuie scris // E - cod de succes: 1 - a fost scris; 0 - nu a fost scris articolul int WriteSec(TARTICOL a) { TART_INDEX a1, ai;

94

Programarea calculatoarelor

long n, n1; int r,r1; r=0; fseek(ind,0,SEEK_END); n=ftell(ind)/sizeof(a1);

lu cr u

if(n>0) { fseek(ind,(n-1)*sizeof(a1),SEEK_SET); fread(&a1,sizeof(a1),1,ind); if(strcmp(a1.cheie,a.cheie)>=0) r1=0; else r1=1; } if((n==0)||(r1==1)) { ai.is=1; strcpy(ai.cheie,a.cheie); fseek(f,0,SEEK_END); n1=ftell(f)/sizeof(a); ai.nr_rel=n1; fseek(ind,0,SEEK_END); fwrite(&ai,sizeof(ai),1,ind); fwrite(&a,sizeof(a),1,f); r=1; } return r;

în

}

În că

//scrierea unui articol in acces direct // I - fisierul de date, articolul care trebuie scris (contine cheia) // E - cod de succes: 1 - a fost scris; 0 - nu a fost scris articolul int WriteKey(TARTICOL a) { char Key[7]; TART_INDEX a1; long n; int r; strcpy(Key,a.cheie); if(SeekKey(Key)) r=0; else { a1.is=1; strcpy(a1.cheie,a.cheie); fseek(f,0,SEEK_END); n=ftell(f)/sizeof(a); a1.nr_rel=n; fwrite(&a,sizeof(a),1,f); fseek(ind,0,SEEK_END); fwrite(&a1,sizeof(a1),1,ind); Sort(); r=1; } return r;

95

Aplicații

}

lu cr u

// Stergerea urmatorului articol, in acces secvential // I // E - cod de succes: 1 - a fost sters; 0 - nu a fost sters articolul int DeleteSec() { TART_INDEX a1; int r; long pos=ftell(ind); fread(&a1,sizeof(a1),1,ind); if(feof(ind)) r=0; else { fseek(ind,pos,SEEK_SET); a1.is=0; fwrite(&a1,sizeof(a1),1,ind); Sort(); r=1; } return r; }

În că

în

// Stergerea articolului cu o anumita cheie, in acces direct // I - cheia articolului care trebuie sters // E - cod de succes: 1 - a fost scris; 0 - nu a fost scris articolul int DeleteKey(char *Key) { int r; if(SeekKey(Key)) r=DeleteSec(); else r=0; return r; } // Suprascrierea ultimului articol citit, cu scopul modificarii // I - articolului care trebuie suprascris // E - cod de succes: 1 - suprascrierea a reusit, 0 - suprascrierea a esuat // esec daca ultima cheie citita difera de a noului articol int RewriteKey(TARTICOL a) { int r; long p; TART_INDEX ai; r=0; p=ftell(ind)/sizeof(TART_INDEX); if(p>0) { fseek(ind,(p-1)*sizeof(TART_INDEX),0); fread(&ai,sizeof(TART_INDEX),1,ind); if(strcmp(ai.cheie,a.cheie)==0) r=1; }

96

Prog gramarea calcullatoarelor

if(r) i { fseek(f,ai.nr_rel*si izeof(TARTI ICOL),0); RTICOL),1,f f); fwrite(&a,sizeof(TAR } r return r; }

id main() voi { int i i,n;

în

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h>

lu cr u

4.5.1. Popularrea inițială a fișierului se realizează prin p adăugareea repetată dee înregistrărri, după crearrea unui fișieer nou. La addăugarea de noi n studenți singura diferrență față de popularea p innițială este căă lucrează cuu un fișier ex xistent. Ca urrmare, cele două d problem me de preluccrare pot fi reezolvate cu aacelași progrram: dacă fișșierul de datee nu există, va v fi întîi creeat. În mod normal, n la poopularea inițială a fișieruului datele see introduc în ordinea o cresccătoare a cheeilor, deci see folosește operația de addăugare în acces a secvennțial. La adăuugarea ulterioară de articcole se foloseește operația de adăugaree în acces direect. În contiinuare sînt prrezentate am mbele variantee de adăugarre.

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume);

În că

Extinde(); E O Open_index( ); i if(f==NULL) { printf("\nFisierul va v fi creat t"); New_index(); }

// 4.5.1.a. POPULARE / ADAUGARE A in n acces dir rect printf("\nA p Adaugarea in n acces dir rect dupa cheie\n"); p printf("\nC od matricol l: "); f fflush(stdi n); e); g gets(x.chei w while(!feof (stdin)) { printf("Nume si pren nume: "); fflush(stdin); gets(x.nume); printf("Grupa: "); ); scanf("%d",&x.grupa)

97

Aplicații

} C Close_index (); printf("\nA p Apasa o tast ta"); g getch();

în

}

lu cr u

printf("A An: "); scanf("%d",&x.an); for(i=0;i<20;i++) x.note[i]=0; : "); printf("Numar note (maxim 20): scanf("%d",&n); for(i=0;i
#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h>

În că

id main() voi { int i i,n;

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume); Extinde(); E O Open_index( ); i if(f==NULL) { printf("\nFisierul va v fi creat t"); New_index(); }

A in n acces secvential // 4.5.1.b. POPULARE / ADAUGARE printf("\nA p Adaugarea in n acces dir rect dupa cheie\n"); p printf("\nC od matricol l: "); f fflush(stdi n);

98

Prog gramarea calcullatoarelor

în

lu cr u

gets(x.cheie); g (stdin)) w while(!feof { printf("Nume si pren nume: "); fflush(stdin); gets(x.nume); printf("Grupa: "); ); scanf("%d",&x.grupa) An: "); printf("A scanf("%d",&x.an); for(i=0;i<20;i++) x.note[i]=0; : "); printf("Numar note (maxim 20): scanf("%d",&n); for(i=0;i
Vizualiizarea tuturorr datelor din fișier: se va genera o listtă într-un fișiier text.

În că

4.5.2.

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h> id main() voi { int i i,n;

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume); Extinde(); E O Open_index( ); i if(f==NULL) { printf("\nFisierul poate p fi de eschis");

99

Aplicații

return; }

printf("\nA p Apasa o tast ta"); g getch(); }

lu cr u

TFISIER g; T g g=fopen("Cu rsanti.txt" ","w"); r rewind(ind) ; \n%20c List f fprintf(g," ta cursanti ilor inregi istrati\n\n",' '); f fprintf(g," \n%-10s %-3 35s Grupa An A Note\n","Cod matr.","Nume si prenume" "); R ReadSec(&x) ; w while(!feof (ind)) { fprintf(g,"\n%10s %3 35s %5d %2d d ",x.cheie e, x.nume, x.grupa, x x. .an); for(i=0;(i<20)&&(x.n note[i]);i+ ++) x.note[i]); ; fprintf(g,"%2d ",x ReadSec(& &x); } f fclose(g); p printf("\nL ntilor se afla a in fisierul Cursa anti.txt"); ; ista cursan C Close_index ();

în

4.5.3. Vizualiizarea datelor despre un student: studdentul este iddentificat pe baza codului matricol introdus de laa tastatură.

În că

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h> id main() voi { int i i,n;

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume); Extinde(); E ); O Open_index( i if(f==NULL) { printf("\nFisierul poate p fi de eschis"); return; } TCHEIE c; T p printf("\nC od matricol l: ");

100

Prog gramarea calcullatoarelor

printf("\nA p Apasa o tast ta"); g getch(); }

lu cr u

gets(c); g w while(!feof (stdin)) { if(SeekKey(c)) { ReadSec(&x); t studentul l:\n"); printf("\nAm gasit : %-35 5s",x.nume); printf("\nNume ricol: %-10 0s",x.cheie e); printf("\nCod matr rupa : %2d / %4d",x.an,x.grupa); printf("\nAn si gr : "); printf("\nNote x.note[i]); ;i++) for(i=0;(i<20)&&(x printf("%2d ",x.note[i]); printf("\n"); } else registrat un u cursant cu acest co od matricol l.\n"); printf("\nNu e inr ricol: "); printf("\n\nCod matr gets(c); } C Close_index ();

în

4.5.4. Vizualiizarea dateloor despre studdenții unei grupe: g de la tastatură se va introducce numărul ggrupei iar lista cu datele studenților vaa fi generată într-un fișierr text.

În că

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h> id main() voi { int i i,n;

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume); Extinde(); E ); O Open_index( i if(f==NULL) { printf("\nFisierul poate p fi de eschis"); return; } TFISIER g; T i int gr;

101 1

Aplicații

în

lu cr u

char num[20]; c rupa: "); p printf("\nG s scanf("%d", &gr); w while(!feof (stdin)) { sprintf(num,"%d.txt" ",gr); g=fopen(num,"w"); rewind(ind); ista cursan ntilor inre egistrati pe entru grupa a fprintf(g,"\n%20c Li \n\n",' ',gr); %d\ fprintf(g,"\n%-10s %-35s % An No ote\n","Cod matr.","Nume si pren nume"); &x); ReadSec(& while(!feof(ind)) { if(x.grupa==gr) 0s %35s %2d d ",x.cheie e, x.nume, x.an); x { fprintf(g,"\n%10 for(i=0;(i<20)&& &(x.note[i] ]);i++) d ",x.note[ [i]); fprintf(g,"%2d } ReadSec(&x); } fclose(g); santilor gr rupei %d se e afla in fisierul printf("\nLista curs ",gr,num); %s" printf("\nGrupa: "); ; scanf("%d",&gr); } C Close_index (); printf("\nA p Apasa o tast ta"); g getch(); }

În că

4.5.5. Înscrierrea unei notee pentru un student: stuudentul este identificat i prin interota va fi adăuugată la sfîrșșitul vectorullui de note, dacă d nu smeddiul codului matricol. No a deepășit lungim mea maximă..

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h> voi id main() { int i i,n;

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume); E Extinde();

102

Prog gramarea calcullatoarelor

Open_index(); O i if(f==NULL) { printf("\nFisierul poate p fi de eschis"); return; }

În că

în

lu cr u

TCHEIE c; T i int nr; p printf("\nC od matricol l: "); g gets(c); w while(!feof (stdin)) { if(SeekKey(c)) { ReadSec(&x); t studentul l:\n"); printf("\nAm gasit printf("\nNume : %-35 5s",x.nume); rupa : %2d / %4d",x.an,x.grupa); printf("\nAn si gr : "); printf("\nNote x.note[i]); ;i++) for(i=0;(i<20)&&(x printf("%2d ",x.note[i]); if(i<20) n "); { printf("\nNoua nota: ote[i]); scanf("%d",&x.no RewriteKey(x); daugat nota a"); printf("\nS-a ad } else ntul are de eja destule e note"); printf("\nStuden printf("\n"); } else registrat un u cursant cu acest co od matricol l.\n"); printf("\nNu e inr ricol: "); printf("\n\nCod matr gets(c); } C Close_index (); printf("\nA p Apasa o tast ta"); g getch();

}

4.5.6. Înscrierrea notelor pentru p o gruppă de studențți: de la tastaatură se intro oduce numărrul grupei, appoi, pentru fiecare f student se afișeazză numele și se cere notaa. Dacă în vecctorul de notee nu mai estte loc pentru încă una, see va afișa unn mesaj coresspunzător și se va trece la următorul sttudent.

#in nclude "indexat.cpp" #in nclude

103

Aplicații

#include <stdlib.h> void main() { int i,n;

lu cr u

printf("\nNumele fisierului indexat:"); fflush(stdin); gets(nume); Extinde(); Open_index(); if(f==NULL) { printf("\nFisierul poate fi deschis"); return; }

În că

în

int gr; printf("\nGrupa: "); scanf("%d",&gr); while(!feof(stdin)) { rewind(ind); ReadSec(&x); while(!feof(ind)) { if(x.grupa==gr) { printf("\nAm gasit studentul:\n"); printf("\nNume : %-35s",x.nume); printf("\nAn si grupa : %2d / %4d",x.an,x.grupa); printf("\nNote : "); for(i=0;(i<20)&&(x.note[i]);i++) printf("%2d ",x.note[i]); if(i<20) { printf("\nNoua nota: "); scanf("%d",&x.note[i]); RewriteKey(x); printf("\nS-a adaugat nota"); } else printf("\nStudentul are deja destule note, se trece la urmatorul"); printf("\n"); } ReadSec(&x); } printf("\nGrupa: "); scanf("%d",&gr); } Close_index(); printf("\nApasa o tasta"); getch();

104

Prog gramarea calcullatoarelor

}

#in nclude "indexat.cpp" #in nclude #in nclude <stdlib.h> id main() voi { int i i,n;

lu cr u

4.5.7. Eliminaarea unui stuudent (exmattriculare, abssolvire etc.): studentul esste identificaat prin codull matricol. Pe P ecran se va v afișa numele său și see va cere connfirmarea expplicită a eliminării.

printf("\nNumele fisie p erului inde exat:"); f fflush(stdi n); g gets(nume);

în

Extinde(); E ); O Open_index( i if(f==NULL) { printf("\nFisierul poate p fi de eschis"); return; }

În că

TCHEIE c; T i int nr; c char r; p printf("\nC od matricol l: "); g gets(c); w while(!feof (stdin)) { if(SeekKey(c)) { ReadSec(&x); t studentul l:\n"); printf("\nAm gasit : %-35 5s",x.nume); printf("\nNume rupa : %2d / %4d",x.an,x.grupa); printf("\nAn si gr : "); printf("\nNote x.note[i]); ;i++) for(i=0;(i<20)&&(x printf("%2d ",x.note[i]); ati sterger rea? (D / N): N "); printf("\nConfirma r=getch(); if((r=='D')||(r=='d')) { DeleteKey(c); ntul a fost t eliminat"); printf("\nCursan } else re, cursant tul ramine inregistrat t"); printf("\nAnular printf("\n");

105 5

Aplicații

} else registrat un u cursant cu acest co od matricol l.\n"); printf("\nNu e inr ricol: "); printf("\n\nCod matr gets(c);

printf("\nA p Apasa o tast ta"); g getch(); }

3. 4.

În că

5.

Temee 1. Scrieți prrogramul carre realizează operațiunea de transferaare a unui studeent de la o gruupă la alta, înn contextul de d mai sus. Scrieți programul care realizeazză operațiuneea de transfeerare a tuturoor studenților dinntr-o grupă către c o altă grrupă. Enunțațți o problem mă de gestiunne a datelor care să se preteze p la org ganizarea indexattă a acestora.. Scrieți un program m multifuncțiional care săă realizeze toate t operațțiunile de gestiune pentru probblema enunțaată anterior. Proiectaați o modalittate mai bunnă (mai geneerală) de impplementare a operațiilor de ggestiune de bază, b eliminînd restricțiile incluse în exemplul dee mai sus. Sugestiie: folosiți modelul m de simulare a orgganizării relaative din sub bcapitolul anteriorr și tema 1 diin același subbcapitol.

în

2.

lu cr u

} C Close_index ();

More Documents from "Ariana Pop"