Sunteți pe pagina 1din 59

47 Aplicații

4.
4 Lucru
ul cu fișșiere

u
Fișierelle constituie o extensie nevolatilă
n a memoriei
m innterne, de aceeea joacă
un rol importannt în problem mele prelucraare automată a datelor. Înn timp ce fișșierele bi-

cr
narre 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 pen-
tru 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 exem-
plu prelucrarea datelor dintrr-o tabelă MS S Excel în caadrul unui prrogram C++)).

dateelor memoraate în fișiere:

• prelucrarea fișierelor bin


lu
Exempllele din acesst capitol vorr prezenta urrmătoarele aspecte

• preluarea daatelor de intrrare din fișiere text,


• prelucrarea masivelor memorate
m în fișiere
f
a

binaree (vectori și matrice),


nare de date organizate secvențial,
s
• simularea oorganizării reelative a fișieerelor binare de date,
m
ale prelucrării
în
• simularea oorganizării in ndexate a fișierelor binaree de date.
Exempllele care urm mează au fostt scrise în mediul
m Visuall Studio 20100, dar pot
fi folosite
fo și în aalte medii dee programaree C++.

4.1. Utiliizarea fișiierelor texxt ca sursse de datee


4.1.1. Fie un fișier text în care


c este memmorat 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 ulte-
rioaare. (Se pressupune că maasivul are o dimensiune rezonabilă pentrup a fi înncărcat în
În

mem moria princippală.)

Pentru a putea alocca memoria dinamică


d neecesară vectoorului preluaat, trebuie
cunnoscută întîi dimensiuneaa lui. O soluțție este efectuuarea unei paarcurgeri supplimenta-
re a fișierului teext, cu număărarea elemenntelor, urmattă de alocareea memoriei și apoi o
nouuă parcurgeree, cu preluareea elementellor și plasarea lor în memmoria internă..
Funcțiaa preluare_veector_1 rezolvă problemaa enunțată mai m sus.
Prog
gramarea calcullatoarelor 48

// 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
flo 1(char * nu
ume, int* n)
n
{ float*
f v,x;
F
FILE* f;
v
v=NULL;
f
fopen_s(&f, nume,"r+");
; //f=fopen
n(nume,"r");
i
if(f)

u
{ //determinare numar elemente ini fisier
*n=0;
fscanf_s(f,"%f",&x); ;
while(!feof(f))

cr
{ (*n)++;
fscanf__s(f,"%f",&xx);
}
//alocare memorie pe entru vecto
or
if(*n>0)
{ v=(float*)malloc(s sizeof(floa
at)*(*n));
//preluare element
rewind(f);
*n=0;
fscanf__s(f,"%f",&x
while(!feof(f))
{ v[(*n)++]=x;
fscanf_s(f,"%f",
te din fisi

x);

,&x);
ier

lu
în
}
}
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
EOOF (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).
În

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
Entter după ultim ma valoare) sau create prrin secvențe de program asemănătoarre aceste-
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 va-
loarre, la salvareea fișierului în format text (cu opțiunnile implicitee) se adaugăă automat
perrechea CR/LF F după ultimma valoare.

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.

u
Exempluu de utilizaree a funcției preluare_vec
p tor_1:

cr
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
//de exemplu, afisarrea unui me
esaj

e
printf("\n\nNu s-a putut
else
{ //prelucrarea vector
//pentru verificarea
printf("\n\nVectorul
for(i=0;i<l;i++)
p

rului
desch

lu
hide fisierrul sau nu sint elemen

, poate fi afisat pe ecran


a functiei,
l preluat are

printf("%5.2f ",a[i]);
a %d elem
e
mente: \n",l);
nte");
în
free(a);
}

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 Se presupune că masi-
(S

vul are o dimennsiune rezonaabilă pentru a fi încărcat în


î memoria principală.)
p

Datorittă modului ded implemenntare în C++ a funcțiilor care preiau date nu-
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 dinn care se
preiau datele.
În

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. PeP 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ă - corespun-
c
de dimensiunilo
d or din prima linie a fișierrului). Scrieții un subproggram care preeia matri-
ceaa din fișier șii o plasează într-o zonă alocată
a dinammic din mem moria internăă în vede-
rea prelucrării uulterioare. (S
Se presupunee că masivul are o dimensiune rezonaabilă pen-
tru a fi încărcat în memoria principală șii că fișierul nu
n este gol.)
Prog
gramarea calcullatoarelor 50

Funcția ppreluare_maatrice_1 rezoolvă problem


ma enunțată mai
m sus.

// I - numele fisieruluii, adreselee unde se depun dimensiunile mat


tricei
pre
eluate
// E - adresa matricei alocate
a dinnamic
flo
oat** preluare_matricee_1(char* nume,
n int* m, int* n)

u
{ float
f **x;
i
int i,j;
F
FILE* f;
x
x=NULL;

cr
f
fopen_s(&f, nume,"r+");
; //f=fopenn(nume,"r");
i
if(f)
{ //preluare dimensiunni matrice
fscanf_s(f,"%d",m);
fscanf_s(f,"%d",n);
//alocare memorie peentru matriice
x=(float**)malloc(si
for(i=0;i<*m;i++)
x[i]=(float*)mallo
izeof(float

oc(sizeof(f
//preluare elemente matrice
for(i=0;i<*m;i++)
for(j=0;j<*n;j++)
,&x[i][j]);
fscanf_s(f,"%f",
lu
t*)*(*m));

float)*(*n));

;
în
fclose(f);
}
r
return x;
}

Deoarrece fișierul conține


c dimeensiunile exaacte ale matrricei, se pot folosi
f bu-
cle cuu număr cun noscut de paași, nefiind nevoie de detectarea
d exxplicită a

sfîrșituului de fișierr. Ca urmaree, această funncț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:


În

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)
//actiuni in caz de esec, de exemplu
e afi
isare mesaj
printf("\n\nNu a puttut fi desc
chis fisier
rul");
e
else
//prelucrarea matriccei preluat
te, de exem
mplu afisaree pe ecran
{ printf("\n\nMatric inii si %d coloane:\n",l,c);
ce cu %d li
for(i=0;i<l;i++)
51 Aplicații

{ for(j=0;j<c;j++)
)
printf("%6.2f",a
a[i][j]);
printf("\n");
}
for(i=0;i<l;i++)
free(a[i]);
free(a);
}

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, se-
parrate prin cîte un spațiu (m matricea estee completă – toate rînduurile au acelaași număr

cr
de elemente). D Dimensiunilee matricei nuu sînt memoorate în fișieer. Scrieți unn subpro-
gram care preiaa matricea diin fișier și o plasează într-o zonă alocată dinamicc din me-
moria internă îîn vederea prelucrării ultterioare. (See presupune că masivul are o di-
mennsiune rezonnabilă pentru a fi încărcatt în memoriaa principală.)

min
enuunțului, număărul de linii ale
e suuficientă num
nummăr de elemeente – confo
lu
Pentru a putea alocaa memoria dinamică neceesară matricei, trebuie înntîi deter-
nate dimensiiunile acesteiia – numărul de linii și numărul
a matricei este
D
n
e egal cu numărul
n
mărarea rînduurilor din fișșierul text. Deoarece
de coloane.
c
de rînduri
r
În condițiile
c
din fiișier, deci
toatte rîndurile au
a același
orm enunțuluui – este sufiicientă număărarea valorilor de pe
în
oriccare rînd penntru a afla nuumă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 deza-
vanntajul că trebbuie alocat sppaț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 anterioa-
ră:

#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;
În

i
int i,j;
F
FILE* f;
c
char* rind;
x
x=NULL;
f
fopen_s(&f, nume,"r+"); n(nume,"r");
; //f=fopen
i
if(f)
{ //numarare rinduri
rind=(char*)malloc(M MAX);
fgets(rind,MAX,f);
*m=0;
Prog
gramarea calcullatoarelor 52

while(!feof(f))
{ (*m)++;
;
fgets(rind,MAX,f);
}
//numarare elemente pe un rind
d - ultimul
l citit
i plus 1
//=numarul de spatii
j=strlen(rind);
*n=1;
for(i=0;i<j;i++)

u
if(rind[i]==' ')
(*n)++;
free(rind);
ntru matric
//alocare spatiu pen ce

cr
x=(float**)malloc(si
izeof(float
t*)*(*m));
for(i=0;i<*m;i++)
x[i]=(float*)mallo float)*(*n));
oc(sizeof(f
//preluare elemente matrice
rewind(f);
for(i=0;i<*m;i++)

}
}
r
for(j=0;j<*n;j++)

fclose(f);

return x;
,&x[i][j]);
fscanf_s(f,"%f", ;

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

Deoareece determin narea număruului de linii din


d fișier (și implicit a numărului
n
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


aceesta nu are m f luată în
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:
numme și prenum me student (m maxim 30 caractere), an nul de studii,, grupa și 200 de note
În

(un
nele dintre ele pot fi 0, cuu semnificațiia că în pozițția respectivăă nu există (încă)
( no-
tă. Scrieți un prrogram care preia acestee date și le memorează
m înntr-un fișier binar or-
gannizat secvențial în vedereea prelucrărillor ulterioaree – cîte o înreegistrare penntru fieca-
re student.
s Fiecare înregistraarea va avea următoarea structură:
Noote
Nume
N și prenume An
n Grupa
nota 1 ota 20
no

char[31] chaar int charr char
53 Aplicații

Deoarece MS Excel adaugă auttomat CR/LF F după fiecaare rînd, incluusiv ulti-
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:

#in
nclude <stdio.h>
#in
nclude <conio.h>
#in
nclude <string.h>

u
#in
nclude <stdlib.h>

efine MAX 200


#de
#de
efine NUME1 "Studenti.csv"

cr
#de
efine NUME2 "Studenti.dat"

voi
id main ()
{ FILE
F *f, *g;
t
typedef struct{ char nume[31];
n

lu
char an;
a
int gr
rupa;
char note[20];
n
} STUDENNT;
S
STUDENT x;
c
char rind[200];
c
char mc[23][31];
i
int n,i,j,k;
în
fopen_s(&f,NUME1,"r");
f ;
i
if(!f)
printf("\n\nFisierull %s nu poa
ate fi deschis",NUME1);
e
else
{ fopen_s(&&g,NUME2,"wb
b");
if(!g)

printf("\n\nFisier
rul %s nu poate
p fi de
eschis",NUME2);
else
{ //preluarea primullui rind di
in fisierul
l text
fgets(rind,MAX,f);
;
//cit timp s-a pre
eluat un ri
ind
while(!feof(f))
{ n=strlen(rind);
În

nte din lin


//separare cuvin nia curenta,
//in vectorul de
e cuvinte mc,
m 1 pe li
inie
i=j=0;
)
for(k=0;k<n;k++)
{ if(rind[k]==',
,')
{ mc[i][j]='\0
0'; //s-a terminat cuuvintul current
i++; //trec la cuvintu
ul urmator
j=0; //nici o litera in
i cuvintul l urmator, inca
}
Prog
gramarea calcullatoarelor 54

else
{ mc[i][j]=rin
nd[k]; //litera crt
c se adau
uga la cuvl crt
j++; //inca o litera
l in c
cuvintul curent
}
}

//din vectorul de
d cuvinte se preiau datele pent
tru student
tul
//curent, cu con
nversie und
de e nevoie
e
strcpy_s(x.nume,
,mc[0]);

u
x.an=atoi(mc[1])
);
x.grupa=atoi(mc[2]);
+)
for(i=0;i<20;i++
x.note[i]=atoi
i(mc[i+3]);
;

cr
//scriere artico
ol in fisie
erul binar
fwrite(&x,sizeof
f(STUDENT),
,1,g);

//preluarea urma
atorului ri
ind din fisierul text
fgets(rind,MAX,f
f);

}
}
_
}
}
fclose(g);

fclose(f);

_getch();
lu
în
Pentru vverificare, coonținutul fișiierului text ar
a putea fi vizzualizat, întrr-un fișier
textt nou, folosinnd următoareea secvență ded program:

fopen_s(&f,NUME2,"r");
f ;

i
if(f)
{ fopen_s(&&g,"Verifica
are.txt","w
w");
frea of(STUDENT),1,f);
ad(&x,sizeo
while(!feof(f))
{ fprintf(g,"\n\n%300s %2d %4d ",x.nume,x
x.an,x.grupa
a);
or(i=0;i<20
fo 0;i++)
fprintf(g,"%2d ",x.note[i]
" ]);
În

fr zeof(STUDENT),1,f);
read(&x,siz
}
intf(g,"\n");
fpri
fclo
ose(g);
fclo
ose(f);
}

Temee
55 Aplicații

1. Pentru exemplul 4.1.1. scrieți o variantă carre să funcțiooneze corect și pentru


fișierelee care nu au CR/LF dupăă ultima valoare.
2. Pentru exemplul 4.11.1. găsiți o altă a rezolvaree, care să nu execute o paarcurgere
suplimeentară a fișieerului pentru determinareea număruluii de elementee ale vec-
torului.
3. Reluați exemplul 4.1.3.
4 incluzîînd o verificcare a matriccei – dacă fiișierul nu
conținee toate elemeentele, conforrm dimensiuunilor din priimul rînd, prrelucrarea
se abanndonează iar pointerul obțținut trebuie să aibă valooarea NULL.

u
4. Pentru exemplul 4.1.4. rezolvarrea prezentattă este supussă unei restriicții (ma-
xim 10000 caractere pe un rînd). Dacă fișieru ul text nu se încadrează în
î această
restricțiie, rezultatele vor fi eronnate. Găsiți o variantă dee rezolvare care să nu

cr
depindăă de această restricție.
r
5. Pentru exemplul 4..1.4 găsiți o metodă de rezolvare caare să nu deepindă de
structurra fizică a fișșierului preluucrat.
6. Pentru exemplul 4..1.4. găsiți o metodă dee rezolvare care c să nu necesite
n o
parcurggere suplimentară a fișieerului pentru determinareea dimensiun nilor ma-

lu
tricei.
7. Reluați exemplul 4.1.4.4 incluzzînd o verificare a matricei – dacă nu toate
rîndurille conțin același număr de d elemente, prelucrarea
p s abandoneaază.
se
8. Fie un fișier text în n format .CSSV. Scrieți unu program carec creează un fișier
text nouu în care sînnt trecute urm mătoarele infformații: nummărul total de
d rînduri
din fișieerul inițial, numărul
n maxxim de cuvinnte pe un rînd și numărull rîndului
respectiiv (primul rîînd are numărul 1), lunggimea celui mai m lung rîn nd, lungi-
în
mea cellui mai scurtt și a celui maim lung cuvîînt (în caracttere) – un cu uvînt este
consideerat șirul cupprins între doi separatori consecutivi
c d același rînnd.
din

4.2. Massive memoorate în fiișiere binaare


Fie un fișier binar în


î care este memorat unn vector cu elemente
e realle (de tip
at). Fiecare eelement constituie un arrticol al fișieerului. Vectoorul are o dim
floa mensiune
prea mare pentrru a fi încărccat în memoorie. Fișierelee folosite în exemplele următoare
u
vorr avea aceastăă structură.

4.2.1. Scrieți unn program caare determinăă elementul maxim din fișier
f și toatee pozițiile
În

c apare ell (pozițiile reelative în fișier).


pe care

Deoarecee numărul dee apariții alee maximului poate fi foaarte mare, poozițiile pe
caree apare acestta vor fi rețin
nute ca vectoor cu elemennte de tip int memorat înttr-un fiși-
er binar.
b

#in
nclude <stdio.h>
#in
nclude <conio.h>
Prog
gramarea calcullatoarelor 56

#de
efine NUME "Vector.dat
t"
#de
efine NUME2 "Pozitii.d
dat"

voi
id main()
{ FILE
F *f, *g;
f
float x, max;
i
int poz;

u
fopen_s(&f,NUME,"rb");
f ;
i
if(!f)
printf("\n\nFisierull %s nu poa
ate fi deschis",NUME);
e
else

cr
{ fopen_s(&&g,NUME2,"wb
b");
fread(&x,sizeof(floaat),1,f);
max=x;
while(!feof(f))
{ if(max<x)
{ max=x;

}
fclose(g);
2,"wb");
fopen_s(&g,NUME2
poz=ftell(f)/siz
zeof(float)
fwrite(&poz,size

else
if(max==x)
)-1;
eof(int),1,
,g);
lu
în
sizeof(floa
{ poz=ftell(f)/s at)-1;
fwrite(&poz,si
izeof(int),
,1,g);
}
&x,sizeof(fl
fread(& loat),1,f);
;
}
fclose(g);
fclose(f);

printf("\n\nMaximul este %5.2f tiile se afla in fisie


f iar pozit erul %s
inar, int)\n",max,NUME
(bi E2);
}
_
_getch();
}

Temăă
În

Scriețți un program
m pentru vizzualizarea fișierului cu ppozițiile de apariție
a a
maximmului.

m care sortează crescător fișierul.


4.2.2. Scrieți unn subprogram

În subproogramul urm
mător sortareaa este realizaată prin metooda bulelor.
//s
sortare vector float memorat
m in fisier bin
nar
57 Aplicații

// I - nume fisier
// E - cod succes: 1- su
ucces, 0 - eroare la deschidere fisier
t Sortare(char* nume)
int
{ FILE
F *f;
i
int n,i,gata;
f
float x,y;
i
int er;

er=0;
e

u
f
fopen_s(&f, nume,"rb+")
);
i
if(f)
{ er=1;
fseek(f,0,SEEK_END); ;

cr
n=ftell(f)/sizeof(fl loat);
if(n>1)
{ gata=0;
while(!gata)
{ gata=1;
for(i=0;i<n-1;i+ ++)
{ fseek(f,i*size
fread(&x,sizeo
fread(&y,sizeo
if(x>y)
{ fseek(f,i*si lu
eof(float),
,SEEK_SET);
of(float),1
1,f);
of(float),1
1,f);

izeof(float
fwrite(&y,si
t),SEEK_SET
izeof(float
fwrite(&x,si
t),1,f);
izeof(float
t),1,f);
T);
în
gata=0;
}
}
}
}
fclose(f);
}

r
return er;
}

4.2.3. Scrieți unn program caare interclaseează două fișiere care coonțin vectori. Ambele
fișiere sînt deja sortate cresccător.
În

#in
nclude <stdio.h>
nclude <conio.h>
#in

efine NUME "Vector.dat


#de t"
#de
efine NUME2 "Vector2.d
dat"
#de
efine NUME3 "Vector_r.dat"

id main()
voi
Prog
gramarea calcullatoarelor 58

{
//4
4.2.3
F
FILE *f, *g,*h;
f
float x,y;
f
fopen_s(&f, ;
NUME,"rb");
i
if(!f)
printf_s("\n\nFisier rul %s nu poate
p fi de
eschis\n",NU
UME);
e
else
{ fopen_s(& &g,NUME2,"rb
b");

u
if(!g)
printf("\n\nFisier rul %s nu poate
p fi de
eschis\n",NU
UME2);
else
{ fopen_s(&h,NUME3," "wb");

cr
fread(& &x,sizeof(fl
loat),1,f);
;
fread(& &y,sizeof(fl
loat),1,g);
;
while((!feof(f)) &&& (!feof(gg)))
if(x<y)
{ fwrite(&x,sizeeof(float),
,1,h);
fread(&x,sizeoof(float),1
1,f);
}
else
{ fwrite(&y,size

}
fread(&y,sizeo

while(!feof(f))
{ fwrite(&x,sizeof
eof(float),
of(float),1
lu
,1,h);
1,g);

f(float),1,
,h);
în
fread(&x,sizeof(float),1,ff);
}
while(!feof(g))
{ fwrite(&y,sizeof f(float),1,
,h);
fread(&y,sizeof(float),1,gg);
}
fclose(h);

fclose(g);
fclose(f);
}
}
_
_getch();
}
În

4.2.4. Scrieți unn subprogram


m care eliminnă dintr-un fișier
f valorile cuprinse înntr-un in-
terv
val dat [a,b].

Deoarecee nu este deffinită operația de ștergeree din fișiere organizate


o seecvențial,
rezoolvarea neceesită un artifiiciu: toate vaalorile care see află în afarra intervaluluui dat vor
fi copiate
c într-uun fișier nou, apoi fișieruul inițial se șterge
ș iar nummele său estte atribuit
nouului fișier creeat. Este posiibil ca noul fișier
f să nu coonțină nici un
u element.
59 Aplicații

//e
eliminare valori din [a,b]
// I - nume fisier, cape
ete interva
al
// E - cod de succes: 1 - succes, 0 - nu s-a putut deschide fisie
erul
t Elimina(char* nume, float a, float
int f b)
{ int
i er;
F
FILE *f,*g;
f
float x;

er=0;
e

u
f
fopen_s(&f, ;
nume,"rb");
i
if(f)
{ fopen_s(& &g,"temp.dat
t","wb");
fread(&x,sizeof(floa at),1,f);

cr
while(!feof(f))
{ if((x<a)||(b<x))
fwrite(&x,sizeoff(float),1,
,g);
fread(& &x,sizeof(fl
loat),1,f);
;
}
fclose(g);

}
}
r
fclose(f);
remove(nume);
rename("temp.dat",nu
er=1;

return er;
ume);

lu
în
4.2.5. Fie un fiișier binar înn care este memorată
m o matrice
m cu elemente
e realle (de tip
floa
at). La începputul fișieruluui sînt mem morate numărrul de linii șii numărul dee coloane
ale matricei, suub formă de număr
n întregg (de tip int); în continuaare se află ellementele
mattricei, în orddine lexicograafică. Scrieții un subprogrram care determină indiccii liniilor
caree au elementtele în ordinee strict crescăătoare.

int
t Indici(char* nume, char*
c nume2
2)
{ int
i er,este,m,n,i,j;
F
FILE *f, *g;
f
float x,y;
În

er=0;
e
f
fopen_s(&f, nume,"rb");
;
i
if(f)
{ er=1;
&g,nume2,"wb
fopen_s(& b");
fread(&m,sizeof(int)),1,f);
fread(&n,sizeof(int)),1,f);
for(i=0;i<m;i++)
{ este=1;
Prog
gramarea calcullatoarelor 60

fseek(f,2*sizeof(iint)+i*n*si
izeof(float
t),SEEK_SET);
fread(&&x,sizeof(fl
loat),1,f);
;
for(j=1;(j<n)&&estte;j++)
{ //fseek(f,2*sizeeof(int)+(i
i*n+j)*size
eof(float),S
SEEK_SET);
fread(&y,sizeof(float),1,ff);
if(x>=y)
este=0;
else
x=y;

u
}
if(este)
fwrite(&i,sizeoff(int),1,g)
);
}

cr
fclose(g);
fclose(f);
}
r
return er;
}

floa
num
Fie un fișier
f binar în
at). La începutul fișierulu
măr întreg (dde tip int); în
lu
î care este memorată
m o matrice cu elemente

n continuare se află elem


grafică. Fișierelle folosite în exemplele următoare

4.2.6. Scrieți unn subprogram


u vo
e
ui este memoorat numărull de linii al matricei,
m
reale (de tip
sub formă de
mentele matriicei, în ordinne lexico-
or avea această structură.

mină coloaneele din matriccea aflată în fișier ca-


m care determ
în
re au
a elementelee în ordine crescătoare.

// I - nume fisier, nume


e fisier re
ezultat
// E - cod succes: 1 - succes,
s 0 - nu s-a pu
utut deschid
de fisierul
l cu ma-
icea
tri

int
t Indici2(char* nume, char* nume
e2)
{ int
i er,este;
F
FILE *f,*g;
f
float x,y;
i
int m,n,i,j;

er=0;
e
În

f
fopen_s(&f, nume,"rb");
;
i
if(f)
{ er=1;
fopen_s(&
&g,nume2,"wbb");
fread(&m,sizeof(int)),1,f);
fseek(f,0,SEEK_END);;
n=(ftell(f)-sizeof(iint))/(size
eof(float)*m);
for(j=0;j<n;j++)
{ este=1;
fseek(f,sizeof(int f(float),SEEK_SET);
t)+j*sizeof
61 Aplicații

fread(&&x,sizeof(fl
loat),1,f);
;
for(i=1;(i<m)&&estte;i++)
{ fseek(f,sizeof(iint)+(i*n+j
j)*sizeof(f
float),SEEK_
_SET);
fread(&y,sizeof(float),1,ff);
if(x>=y)
este=0;
else
x=y;
}

u
if(este)
fwrite(&j,sizeoff(int),1,g)
);
}
fclose(f);

cr
fclose(g);
}
r
return er;
}

lu
4.2.7. Scrieți unn subprogram
m care determmină suma elementelor
e d pe diagon
de nala prin-
cipaală și suma eelementelor de pe diagonnala secundaară a matricei aflate în fișșier, dacă
mattricea e pătraată.

// I - nume fisier, adre


esele unde se depun cele 2 sume
în
// E - cod eroare: 0 - succes,
s 1 - nu s-a pu
utut deschidde fisierul
l, 2 -
tricea nu e patrata
mat
int
t SumeDiagonale(char * nume, flo
oat *sp, fl
loat* ss)
{ int
i er;
F
FILE *f;
f
float x;
i
int m,n,i;

er=1;
e
f
fopen_s(&f, nume,"rb");
;
i
if(f)
{ fread(&m,sizeof(int)),1,f);
fseek(f,0,SEEK_END);;
n=(ftell(f)-sizeof(i eof(float)*m);
int))/(size
În

if(m!=n)
er=2;
else
{ er=0;
*sp=0;
*ss=0;
for(i=0;i<m;i++)
{ fseek(f,sizeof(iint)+(i*m+i
i)*sizeof(f
float),SEEK_
_SET);
fread(&x,sizeof(float),1,f
f);
*sp+=x;
Prog
gramarea calcullatoarelor 62

fseek(f,sizeof(i
int)+(i*m+n
n-i-1)*size
eof(float),S
SEEK_SET);
fread(&x,sizeof(float),1,f
f);
*ss+=x;
}
}
fclose(f);
}
r
return er;
}

u
4.2.8. Scrieți unn subprogram
m care determ
mină produsuul a două maatrice memorrate în fi-
șierre binare.

cr
// I - numele celor douaa fisiere, numele fisierului rezulat
// E - cod eroare: 0 - succes,
s 1 - nu s-a puutut deschid
de primul fisier
f
// 2 - nu
n s-a putu ut deschide
e al doilea fisier
//

i
F
FILE
f
float
i
int
er;
*f,*g,*h;
x,y,z;
3 - dimensiuni

m,n,p,q,i,j,k;
d
t Produs(char* nume1, char* nume
int
{ int

lu
nepotrivit
te pentru inmultire
e2, char* nume3)
n
în
fopen_s(&f,nume1,"rb")
f );
i
if(!f)
er=1;
e
else
{ fopen_s(&&g,nume2,"rb
b");
if(!g)
er=2;

else
{ fread(&&m,sizeof(in
nt),1,f);
fseek(f,0,SEEK_END
D);
n=(ftell(f)-sizeof
f(int))/(m*
*sizeof(flo
oat));
&p,sizeof(in
fread(& nt),1,g);
if(n!=p)
er=3;
În

else
{ er=0;
END);
fseek(g,0,SEEK_E
q=(ftell(g)-size
eof(int))/(
(p*sizeof(f
float));
fopen_s(&h,nume3
3,"wb");
fwrite(&m,sizeof
f(int),1,h)
);
for(i=0;i<m;i++)
)
for(j=0;j<q;j+
++)
{ z=0;
eof(int)+i*
fseek(f,size *m*sizeof(f
float),SEEK_
_SET);
63 Aplicații

for(k=0;k<n;
;k++)
{ fread(&x,s
sizeof(floa
at),1,f);
fseek(g,si
izeof(int)+
+(k*p+j)*si
izeof(float),SEEK_SET)
);
fread(&y,s
sizeof(floa
at),1,g);
z+=x*y;
}
izeof(float
fwrite(&z,si t),1,h);
}
fclose(h);

u
}
fclose(g);
}
fclose(f);

cr
}
r
return er;
}

lu
Temee
1. Scrieți un n program caare creează un u fișier cu sttructura desccrisă pen-
tru exxemplul 4.2.1. și un prrogram care permite vizzualizare connținutului
unui asttfel de fișier (într-un fișieer text).
2. Scrieți un program care creeazăă un fișier cuu structura descrisă
d penttru exem-
plul 4.22.5. și un proogram care permite
p vizuaalizare conținnutului unui astfel de
fișier (îîntr-un fișier text).
în
3. Scrieți un program care creeazăă un fișier cuu structura descrisă
d penttru exem-
plul 4.22.5. și un proogram care permite
p vizuaalizare conținnutului unui astfel de
fișier (îîntr-un fișier text).
4. Scrieți un subprogrram care caalculează proodusul dintree un vector memorat
într-un fișier binar (cu
( structura descrisă maai sus) și o matrice
m memo orată într-
un fișieer binar (cu sttructura desccrisă la exem mplul 4.2.6.).

5. Scrieți un subprograam care deteermină dacă o matrice memorată într-un fișier


binar (ccu una din sttructurile descrise mai suus) este supeerior triunghiulară. În
caz afirrmativ, se va calcula și deeterminantul acestei matrrice.
6. Scrieți un program care adaugăă un vector memorat m într--un fișier binnar ca ul-
tima cooloană a uneii matrice mem morate într-uun fișier binaar (cu una din n structu-
rile descrise mai suss), dacă dimeensiunea estee potrivită.
În

4.3. Fișieere binaree de date,, organiza


ate secven
nțial
Exercițiiile următoarre vor exempplifica realizzarea operațiunilor de gestiune de
bazză asupra fișiierelor binaree de date.

4.3.1. Fie un fişşier organizaat secvenţial, cu date desspre studenţiii unei faculttăţi. Arti-
coleele au următtoarea structuură:
Prog
gramarea calcullatoarelor 64

N
Nume şi prenuume An dee studiu G
Grupa Nr. discipline
d Note obţinnute
1 2 … 15
char [30] chhar int char
chhar char char

Scrieți uun program C pentru adăăugarea de arrticole în aceest fișier.

u
#in
nclude <stdio.h>
#in
nclude <conio.h>

pedef struct { char nu


typ ume[30];

cr
char an
n;
int gru
upa;
char nr
rd;
char no
ote[15];
} STUDENT
T;

id main()
voi
{ FILE
F
S
c
char
i
int
*f;
STUDENT

i;
x;
nume_f[20];

printf("\nNume fisier: ");


p
lu
în
g
gets(nume_f );
f
fopen_s(&f, +");
nume_f,"rb+

if(!f)
i
printf("\nFisierul %s
% nu poate e fi deschi
is");
e
else
{ fseek(f,0,SEEK_END);;

printf("\nNume si prrenume (sauu CTRL-Z): ");


fflush(stdin);
gets(x.nume);
while(!feof(stdin))
{ printf("An : "));
;
scanf("%d",&x.an);
printf("Grupa : "));
În

pa);
scanf("%d",&x.grup
printf("Numar disc
cipline: "));
scanf("%d",&x.nrd)
);
for(i=0;i<x.nrd;i+
++)
{ printf("\tNota %2d:
% ",i);
scanf("%d",&x.no
ote[i]);
}
fwrite(&x,sizeof(S
STUDENT),1,,f);
printf("\nNume si prenume (ssau CTRL-Z): ");
fflush(stdin);
65 Aplicații

gets(x.nume);
}
fclose(f);
}
p
printf("\n\ nAdaugarea s-a termin
nat");
p
printf("\nA
Apasa o tastta");
_
_getch();
}

u
4.3.2. Fie fișierrul prezentat în exercițiull anterior. Sccrieţi un proogram C penttru sorta-
rea datelor din fişier
f după annul de studiuu şi grupă, prrin metoda buulelor.

cr
#in
nclude <stdio.h>
#in
nclude <conio.h>

typ
pedef struct { char nu
ume[30];

id main()
voi
char an
n;
int grupa;
rd;
char nr
char no
ote[15];
} STUDENT
T; lu
în
{ FILE
F *f;
S
STUDENT x;
c
char nume_f[20];
i
int i,n,j,gata;
S
STUDENT y;

fopen_s(&f,nume_f,"rb+
f +");

i
if(!f)
printf("\nFisierul %s
% nu poatee fi deschi
is");
e
else
{ fseek(f,0,SEEK_END);;
n=ftell(f)/sizeof(STTUDENT);
gata=0;
while(!gata)
În

{ gata=1;
)
for(i=0;i<n-1;i++)
{ fseek(f,i*sizeof
f(STUDENT),
,SEEK_SET);
fread(&x,sizeof(STUDENT),1
1,f);
fread(&y,sizeof(STUDENT),1
1,f);
if( (x.an>y.an) || ((x.an=
==y.an)&&(x
x.grupa>y.grupa)) )
{ gata=0;
eof(STUDENT
fseek(f,i*size T),SEEK_SET
T);
fwrite(&y,size
eof(STUDENT
T),1,f);
fwrite(&x,size
eof(STUDENT
T),1,f);
Prog
gramarea calcullatoarelor 66

}
}
}
fclose(f);
printf("\nFisierul %s
% a fost sortat
s crescator dupa an si grup
pa",
me_f);
num
}
p
printf("\nA
Apasa o tast
ta");
_
_getch();

u
}

4.3.3. Fie fișierrul prezentat în exercițiul 4.3.1. Consiiderînd că fişşierul este soortat după
anuul de studiu şşi grupă, scriieţi un progrram C care generează
g înttr-un fişier teext o listă

cr
cu mediile
m studdenţilor, media fiecărei grrupe, media fiecărui an dde studiu şi media
m ge-
nerrală.

#in
nclude <stdio.h>
#in
nclude <conio.h>

pedef struct { char nu


typ ume[30];
char an
n;
int gru
upa;
lu
în
char nr
rd;
char no
ote[15];
} STUDENT
T;

id main()
voi
{ FILE
F *f,*g;
S
STUDENT x;
c
char nume_f[20];

i
int i;
c
char can;
i
int cgr,na,nf,ng;
f
float mf,ma,mg,s;

fopen_s(&f,nume_f,"rb+
f +");
i
if(!f)
În

printf("\nFisierul %s
% nu poatee fi deschi
is");
e
else
{ //operatii initiale la nivel de
d fisier
&g,"Lista me
fopen_s(& edii.txt","
"w");
fprintf(g,"Lista med
diilor stud
dentilor, grupelor
g si anilor\n\n
n");
mf=0;
nf=0;
fread(&x,sizeof(STUD
DENT),1,f);
;
while(!feof(f))
{ //operatii initial
le la nivel
l de an
67 Aplicații

can=x.an;
ma=0;
na=0;
fprintf(g,"\n\nAnul: %2d",can);
while((can==x.an)&&(!feof(f)))
{ //operatii initiale la nivel de grupa
cgr=x.grupa;
mg=0;
ng=0;

u
fprintf(g,"\n\n\tGrupa: %4d",cgr);
while((can==x.an)&&(cgr==x.grupa)&&(!feof(f)))
{ //prelucrare articol
s=0;

cr
for(i=0;i<x.nrd;i++)
s+=x.note[i];
s=s/x.nrd;
mg+=s;
ng++;
fprintf(g,"\n\t\t%-30s %5.2f",x.nume,s);

mg/=ng;
lu
fread(&x,sizeof(STUDENT),1,f);

//operatii finale la nivel de grupa

fprintf(g,"\n\tMedia grupei %4d este %5.2f",cgr,mg);


ma+=mg;
na++;
în
}
//operatii finale la nivel de an
ma/=na;
fprintf(g,"\nMedia anului %2d este %5.2f",can,ma);
mf+=ma;
nf++;
}

//operatii finale la nivel de fisier


mf/=nf;
fprintf(g,"\nMedia generala este %5.2f",mf);
fclose(f);
fclose(g);
printf("\nLista se afla in fisierul \"Lista medii.txt\"");
}
În

printf("\nApasa o tasta");
_getch();
}

4.3.4. Fie 2 fişiere organizate secvenţial, cu date despre impozitele datorate statului
pe raza a 2 administraţii financiare. Articolele au următoarea structură:

CNP Nume şi Impozit anual pe clădiri Impozit anual pe clădiri


Adresa
contribuabil prenume şi terenuri, calculat şi terenuri, plătit
char [14] char [30] char [50] float float
Prog
gramarea calcullatoarelor 68

Consideerînd fişiereele sortate crrescător duppă valoarea impozitului calculat,


scriieţi un prograam C pentru interclasarea celor 2 fişiiere.

#in
nclude <stdio.h>
nclude <conio.h>
#in

u
typ
pedef struct { char cn
np[14];
char nu
ume[30];
char ad
dresa[50];

cr
float ic,ip;
i
} CONTRIB
BUABIL;

id main()
voi
{ FILE
F *f,*g,*h;
C
CONTRIBUABI L x,y;
c
char

p
g
f
nume_f[20];

printf("\nPrimul fisie
gets(nume_f
fopen_s(&f,
i
if(!f)
);
er: ");

nume_f,"rb"

printf("\nFisierul %s
");

% nu poate
lu
e fi deschi
is",nume_f);
în
e
else
{ printf("\nAl doilea fisier: ") );
fflush(stdin);
gets(nume_f);
fopen_s(&&g,nume_f,"rrb");
if(!g)
printf("\nFisierul ate fi deschis",nume_f
l %s nu poa f);

else
{ printf("\nFisier rezultat:
r "
",nume_f);
fflush(stdin);
gets(nume_f);
fopen_s(&h,nume_f,,"wb");
&x,sizeof(CO
fread(& ONTRIBUABIL
L),1,f);
fread(&
&y,sizeof(COONTRIBUABIL
L),1,g);
În

while((!feof(f)) &&
& (!feof(gg)))
if(x.ic<y.ic)
{ fwrite(&x,size
eof(CONTRIB
BUABIL),1,h
h);
fread(&x,sizeo
of(CONTRIBU
UABIL),1,f);
}
else
{ fwrite(&y,size
eof(CONTRIB
BUABIL),1,h
h);
fread(&y,sizeo UABIL),1,f);
of(CONTRIBU
}
69 Aplicații

while(!feof(f))
{ fwrite(&x,sizeof
f(CONTRIBUA
ABIL),1,h);
fread(&x,sizeof(CONTRIBUAB
BIL),1,f);
}
while(!feof(g))
f(CONTRIBUA
{ fwrite(&y,sizeof ABIL),1,h);
fread(&y,sizeof(CONTRIBUAB
BIL),1,f);
}
fclose(h);

u
fclose(g);
}
fclose(f);
}

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

4.3.5. Fie fișierrul prezentat în exercițiull anterior. Sccrieţi un proggram C care generea-

lu
ză într-un
î fişierr text o listă cu contribuaabilii (contribbuabilul) cu cea mai marre datorie
neaachitată cătree stat.

#in
nclude <stdio.h>
#in
nclude <conio.h>
în
typ
pedef struct { char cn
np[14];
char nu
ume[30];
char ad
dresa[50];
float ic,ip;
i
} CONTRIB
BUABIL;

id main()
voi
{ FILE*
F f,*g,*h;
C
CONTRIBUABI L x;
f
float max;
c
char nume_f[20];
i
int poz;
În

printf("\nNume fisier: ");


p
g
gets(nume_f );
f
fopen_s(&f, ");
nume_f,"rb"
i
if(!f)
printf("\nFisierul %s
% nu poatee fi deschi
is",nume_f);
e
else
{ fopen_s(&
&g,"temp.datt","wb");
fread(&x,sizeof(CONTTRIBUABIL),
,1,f);
max=0;
while(!feof(f))
Prog
gramarea calcullatoarelor 70

{ if(max<x.ic-x.ip)
{ max=x.ic-x.ip;
zeof(CONTRI
poz=ftell(f)/siz IBUABIL) - 1;
fclose(g);
fopen_s(&g,"temp
p.dat","wb"
");
fwrite(&poz,size
eof(int),1,
,g);
}
else
if(max=x.ic-x.ip
p)

u
{ poz=ftell(f)/s TRIBUABIL) - 1;
sizeof(CONT
fwrite(&poz,si
izeof(int),
,1,g);
}
&x,sizeof(CO
fread(& ONTRIBUABIL
L),1,f);

cr
}
rewind(g);
&h,"Lista.tx
fopen_s(& xt","w");
fprintf(h,"Lista cu cele mai mari
m datori
ii neplatite
e:\n\n");
fprintf(h,"\nDatoria
a maxima es
ste %8.2 le
ei”, max);
fprintf(h,” neachita
ata de urma
atorii:\n”);
fread(&poz,sizeof(in
while(!feof(g))

}
&x,sizeof(CO
fread(&

fread(&
nt),1,g);

f(CONTRIBUA
{ fseek(f,poz*sizeof
ONTRIBUABIL
L),1,f);
fprintf(h,"\n%14s %30s %50s" lu
ABIL),SEEK_
_SET);

",x.cnp,x.n
&poz,sizeof(int),1,g);
;
nume,x.adresa);
în
fclose(g);
fclose(h);
printf("\nLista se afla
a in fis
sierul List
ta.txt");
remove("temp.dat");
fclose(f);
}
p
printf("\nG ata, apasa o tasta");
;

_
_getch();
}

4.3.6. Fie un fişşier organizaat secvenţial, cu date desppre flota de camioane


c a unei
u soci-
etăţţi de transporrt. Articolelee au următoarea structurăă:

Număr de Capacitatte
În

Dată achhiziţie km
m parcurşi În cursăă/în garaj
înmatriculare
î transporrt
zi lunnă an mc t
char [8] float c
char
char chaar int float flloat

Scrieţi uun program C care înregiistrează plecarea în cursăă a unor autoovehicule.


Sfîrrşitul introduucerii datelorr este marcat standard.
71 Aplicații

#include <stdio.h>
#include <conio.h>
#include <string.h>

typedef struct { char zi;


char luna;
int an;
} DATA;

u
typedef struct { float mc;
float t;
} CAPACITATE;

cr
typedef struct { char nr[8];
DATA data;
float km;
CAPACITATE cap;
char inc; // 1 - in cursa; 0 - in garaj
} CAMION;

void main()
{ FILE *f;
CAMION x;
char r;
char nr[8];
char nume_f[20];
lu
în
int gasit;

printf("\nNume fisier: ");


gets(nume_f);
fopen_s(&f,nume_f,"rb+");
if(!f)
printf("\nFisierul %s nu poate fi deschis");

else
{ printf("\nNr inmatriculare (sau CTRL+Z): ");
fflush(stdin);
gets(nr);
while(!feof(stdin))
{ rewind(f);
gasit=0;
În

fread(&x,sizeof(CAMION),1,f);
while((!feof(f)) && (!gasit))
{ if(strcmp(nr,x.nr)==0)
{ gasit=1;
printf("\nVehiculul cu nr. %s ",x.nr);
if(x.inc==1)
printf("se afla deja in cursa!");
else
{ printf("pleaca acum in cursa? (D/N)");
r=_getch();
Prog
gramarea calcullatoarelor 72

if((r=='D') || (r=='d'
'))
{ x.inc=1;
tell(f)-siz
fseek(f,ft zeof(CAMION
N),SEEK_SET);
fwrite(&x,
,sizeof(CAM
MION),1,f);
}
}
}
fread(&x,sizeof(CAMION),1,
,f);
}

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

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

Nr.. matri- Numee și prenume


col
int c
student
char[30]
An
char lu
4.3.7. Fie un fişşier organizaat secvenţial, cu articole de

Grupăă
int char
d următoareea structură:

Nr. discipline
1
Note obţinutee:
2 …
char cchar char
20
char
în
Să se sccrie program
mul C pentru realizarea unnei liste cu studenţilor
s in
ntegralişti
(înttr-un fișier teext).

#in
nclude <stdio.h>

nclude <conio.h>
#in

pedef struct { int nrm


typ mat;
char nu
ume[30];
char an
n;
int gru
upa;
char nr
rd;
char no
ote[20];
În

} 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

fopen_s(&f,nume_f,"rb"
f ");
i
if(!f)
printf("\nFisierul %s% nu poatee fi deschi
is");
e
else
{ fopen_s(&&g,"Lista.txxt","w");
fprintf(g,"Lista stu udentilor integralist
i ti\n\n");
fprintf(g,"\n Nr. %- upa Note","Nume");
-30s An Gru
nr=0;
fread(&x,sizeof(STUD DENT),1,f);
;

u
while(!feof(f))
{ restante=0;
for(i=0;i<x.nrd;i+++)
if(x.note[i]<5)

cr
restante=1;
if(!restante)
{ nr++;
fprintf(g,"\n%4d d %5d ",nr,x.nume,x.an,x.grupa);
d %-30s %2d ;
for(i=0;i<x.nrd;;i++)
fprintf(g,"%5.2f ",x.notte[i]);

}
}

if(!nr)
&x,sizeof(ST
fread(&

printf("\n\nNu exi
else
printf("\n\nLista se afla in
lu
TUDENT),1,f
f);

u student integralist
ista nici un t");

n fisierul Lista.txt");
în
fclose(g);
fclose(f);
}
p
printf("\nG ata, apasa o tasta");
;
_
_getch();
}

4.3.8. Fie un fişşier organizaat secvenţial, cu articole de


d următoareea structură:

Nr.
N înmatriculare Maarca An fabricaţie Nr. km Valloare
char[8] charr[20] int long float

Să se realizeze proogramul C pentru listareaa într-un fişier text a autooturisme-


În

lor mai vechi dee 10 ani şi cuu peste 3000000 km.

#in
nclude <stdio.h>
#in
nclude <conio.h>

pedef struct { char nr


typ rm[8];
char ma
arca[20];
int anf
f;
Programarea calculatoarelor 74

long km;
float val;
} VEHICUL;

void main()
{ FILE *f,*g;
VEHICUL x;
int an,ani,nr;
long km;

u
char nume_f[20];

printf("\nNume fisier: ");


gets(nume_f);

cr
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);

lu
//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
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)
În

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.

4.4. Simu
ularea organizării relative a fișiereloor binare

u
Pentru rrezolvarea problemelor
p d gestiune a fișierelor binare
de b de datte organi-
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ă,

cr
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
prin me.

tom
Fișierul R

aflăă în primul ooctet al artico


lu
Relative.cpp conține funccțiile care im
ne de bază pentru fișierele organizatee relativ. Inddicatorul de stare
tiun
mplementeazăă operațiunille de ges-
s este adăăugat au-
mat articoleloor logice, obțținînd articollele fizice alee fișierului. Indicatorul
I
olelor fizice.. Deoarece inndicatorul dee stare rămîn
de stare se
ne ascuns
în
î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 indica-
toruul de stare înn primul octtet); această limitare a grradului de geeneralitate al subpro-
gramelor este uun compromis acceptabil.

#in
nclude <stdio.h>
nclude <malloc.h>
#in
#in
nclude <string.h>

n fisier (n
// numar total spatii in nr. articol
le fizice)
// I - fisierul, dimensi
iunea unui articol lo
ogic
// E - nr. articole fizi
ice (-1 dac
ca fisierul
l nu e deschis)
În

t NrSpatii(FILE* f, lo
int ong dim)
{ 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);
;
}
Programarea calculatoarelor 76

return nr;
}

// 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;

u
if(f)
nr=ftell(f)/(dim+1);
return nr;
}

cr
// 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<nr;i++)
lu
în
fwrite(art,dim+1,1,f);
er=0;
free(art);
}
return er;
}

// 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)
În

if(p<NrSpatii(f,dim))
{ fseek(f,p*(dim+1),SEEK_SET);
er=0;
}
else
er=1;
return er;
}

// citire in acces secvential, urmatorul articol


77 Aplicații

// 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))

u
{ if(art[0])
{ er=0;
memcpy(adresa,art+1,dim);
}

cr
else
fread(art,dim+1,1,f);
}
if(er==1) er=2;
free(art);
}

}
return er;

// citire in acces direct


lu
// 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
în
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);
În

}
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;
Programarea calculatoarelor 78

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)

u
er=2;
else
{ er=0;
memcpy(art+1,adresa,dim);

cr
art[0]=1;
Pozitionare(f,dim,poz);
fwrite(art,dim+1,1,f);
}
free(art);
}

}
return er;

lu
// 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)
în
{ char* art;
int n,er=1;

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);
}
În

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 Aplicații

{ c
char* art;
i
int er;
e
er=Pozition are(f,dim,p
poz);
i
if(!er)
{ art=(char*)malloc(diim+1);
fread(art,dim+1,1,f));
if(art[0]==0)
er=2;
else

u
{ er=0;
art[0]=0;
Pozitionare(f,dim,,poz);
fwrite(art,dim+1,11,f);

cr
}
free(art);
}
r
return er;
}

refo
logică:

Tip Num
me/denumire
lu
4.4.1. Fie un fişşier organizaat relativ, cu date despre colaboratoriii unei societăăţi de co-
lecttare a materiialelor refolo
osibile. Fiecaare colaborato
A
or predă un ssingur tip dee material
olosibil. Dateele se referă la un an callendaristic. Articolele au următoarea structură

Cantitaate predată lunnar


în
material
m coolaborator 1 2 3 4 5 6 7 8 9 10 11 12
char c
char [20] i
int int int int int int int intt int int int int

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 in-
trod
ducerii dateloor de la tastaatură este maarcat standardd.

#in
nclude <stdio.h>
nclude <conio.h>
#in
#in
nclude "Relative.cpp"
În

pedef struct { char ti


typ ipm;
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;
Prog
gramarea calcullatoarelor 80

long dim;
l
c
char nume_f[20];

d
dim=sizeof( COLABORATOR
R);

printf("\nNume fisier colaborato


p ori: ");
g
gets_s(nume _f);
i
if(fopen_s( "wb+"))
&f,nume_f,"
printf("\nFisierul %s% nu a puttut fi deschis", nume_
_f);

u
e
else
{ printf_s("\nCod cola aborator no
ou: ");
scanf_s("%d",&codc); ;
while(!feof(stdin))

cr
{ er=CitestePozitia(f,dim,codc c,&x);
if(er==2)
printf("\nCodul introdus apartine
a de
eja altui co
olaborator"
");
else
{ printf("\nNume/ddenumire co
olaborator: ");
fflush(stdin);
gets(x.nume);
printf("Tip mate
scanf("%c",&x.ti
if(x.tipm<'a')
x.tipm=x.tipm+
printf("Cantitat
for(i=0;i<12;i++
erial (H/S/
ipm);

+'a'-'A';

+)
lu
/A/F): ");

itializeaza cu 0");
tile se ini
în
x.cant[i]=0;
ScriePozitia(f,ddim,&x,codc
c);
}
_s("\n\nCod colaborato
printf_ or nou: ");
scanf_s("%d",&codcc);
}
fclose(f);

}
p
printf("\nAApasa o tastta!");
_
_getch();
}

4.4.2. Fie fișierrul descris în


n exercițiul anterior.
a Să se scrie progrramul C penntru afişa-
rea colaboratoruului (colaborratorilor) carre au predat cantități anuuale maximee dintr-un
În

anuumit tip de mmaterial refolosibil (introodus de la taastatură). Se vor preciza cod, nu-
me//denumire şi cantitate tottală.

#in
nclude <stdio.h>
#in
nclude <conio.h>
#in
nclude "Relative.cpp"
81 Aplicații

typedef struct { char tipm;


char nume[20];
int cant[12];
} COLABORATOR;

void main()
{ FILE* f;
COLABORATOR x;
unsigned int codc;

u
int er,n;
long dim;
char nume_f[20],mat;
int cod_max[50],nr,max,s,i;

cr
dim=sizeof(COLABORATOR);

printf("\nNume fisier colaboratori: ");


gets_s(nume_f);
if(fopen_s(&f,nume_f,"rb+"))

else
{ nr=0;
max=0;
lu
printf("\nFisierul %s nu a putut fi deschis", nume_f);

printf("Tip material (H/S/A/F): ");


scanf("%c",&mat);
if(mat<'a')
în
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)
În

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<nr;i++)
{ CitestePozitia(f,dim,cod_max[i],&x);
printf("\n%6d %-30s",cod_max[i],x.nume);
}
Prog
gramarea calcullatoarelor 82

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

4.4.3. Fie un fişşier organizaat relativ, cu date despre facturile em


mise de o sociietate co-
merrcială. Articoolele au urmăătoarea strucctură logică:

u
Nume clientt Dataa facturării Nr. produse Valoare prooduse
zi luna an 1 2 … 50
char [30] intt
char char int flooat float float

cr
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.

#in
nclude <stdio.h>
#in
nclude <conio.h>
#in
nclude "Relative.cpp"
lu
în
pedef struct { char nu
typ ume[30];
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;
În

d
dim=sizeof( FACTURA);

printf("\nNume fisier: ");


p
g
gets(nume_f );
e
er=fopen_s( "rb");
&f,nume_f,"
i
if(er)
printf("\nNu se poatte deschide
e fisierul %s",nume_f);
e
else
{ printf("\nNume fisieer lista: ");
"
83 Aplicații

fflush(stdin);
gets(nume_f);
&g,nume_f,"w
fopen_s(& w");
printf("\nAnul cauta
at: ");
scanf("%d",&an);
inima: ");
printf("\nValoare mi
scanf("%d",&val_lim)
);
fprintf(g,"Lista fac
cturilor cuu valoarea mai mare de
ecit %d din
n anul
\n\n",val_lim,an);
%d\

u
fprintf(g,"\nNr.fact
t %-30s Valloare","Num
me / denumire client")
);

er=CitesteUrmatorul(f,dim,&x);
;
while(!er)

cr
{ 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
fprintf(g,"\n% % ia(f,dim)-1,x.nume,s);
;

}
}
}
er=CitesteUrmatoru

fclose(f);
fclose(g);
ul(f,dim,&x

printf("\nLista se afla
a
x);

in fis
lu
sierul %s",nume_f);
î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ă:

Denumire Caantităţi vîndutte lunar:


U.M. Preţ
P unitar
produs 1 2 … 12
char[30] char[5] float int int 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 intro-
ducc de la tastatuură. Sfîrşitul introducerii datelor de laa tastatură esste marcat staandard.
În

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

pedef struct { char de


typ enumire[30]
];
char um
m[5];
float pretu;
p
Programarea calculatoarelor 84

int cant[12];
} PRODUS;

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

u
dim=sizeof(PRODUS);

printf("\nNume fisier: ");

cr
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)
lu
printf("\nCodul %d nu crespunde unui produs",codp);
else
{ printf("\nCodul %d corespunde produsului:\n",codp);
în
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);
}
În

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 Data achiziţiei Valoare


Tip fond fix Gestionar
fond fix an lună zi inventar
85 Aplicații

char[30] char[220] int char chaar float char[3


30]

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

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

cr
pedef struct { char de
typ enumire[30]
];
char ti
ip[20];
int an;
;
char lu
una;
char zi
i;

lu
float val_inv;
v
char ge
est[30];
} FOND_FI
IX;

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

d
dim=sizeof( FOND_FIX);

printf("\nNume fisier: ");


p
g
gets(nume_f );

e
er=fopen_s( "rb");
&f,nume_f,"
i
if(er)
printf("\nNu se poatte deschide
e fisierul %s",nume_f);
e
else
{ printf("\Numar invenntar: ");
scanf("%d",&nri);
while(!feof(f))
În

{ er=CitestePozitia(f,dim,nri,,&x);
if(er)
printf("\Numarul tar %d nu crespunde unui fond
l de invent
x",nri);
fix
else
{ printf("\Numarul
l de invent
tar %d core
espunde fonddului
x:\n",nri);
fix
ire: %s \nT
printf("\nDenumi Tip: %s \ndata achizittiei:
%d.%d.%d",x.denumire,x.ttip,x.zi,x.
.luna,x.an);
printf("\nValoar
re inventar
r: %8.2f",x
x.val_inv);
Prog
gramarea calcullatoarelor 86

printf("\nGestio
onar: %s",x
x.gest);
}
printf("\nNumar in
nventar: ")
);
scanf("%d",&nri);
}
fclose(f);
}
p
printf("\nA
Apasa o tast
ta!");
_
_getch();

u
}

4.4.6. Fie un fişşier organizaat relativ, cu articole


a de următoarea sttructură:

cr
Nume şi prenum
me An de studiu Grrupa Nr. discipline Note obţiinute
1 2 … 15
char [30] chaar innt char
char char char

Număruul matricol inndică număruul relativ al articolului


a înn fişier.

în urma
u

lu
Scrieţi uun program C pentru însscrierea interractivă în fişşier a notelorr obţinute
susţineerii unor exaamene. Fiecaare materie are a asociată o anumită poziție
vecctorul de notee. Sfîrşitul inntroducerii daatelor este marcat
m standarrd.
p în
în
#in
nclude <stdio.h>
#in
nclude <conio.h>
#in
nclude "Relative.cpp"

pedef struct { char nu


typ ume[30];
char an
n;
int gru
upa;

char nr
rd;
char no
ote[15];
} STUDENT
T;

id main()
voi
{ FILE*
F f;
S
STUDENT x;
În

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 poatte deschide
e fisierul %s",nume_f);
87 Aplicații

else
e
{ printf("\Numar matri icol: ");
scanf("%d",&nrm);
while(!feof(f))
{ er=CitestePozitia(f,dim,nrm, ,&x);
if(er)
printf("\Numarull matricol %d nu crespunde unui student",n
nrm);
else
{ printf("\Numarull matricol %d corespu
unde student
tului:\n",n
nrm);

u
printf("\nNume: %s ",x.numme);
printf("\nAn: %dd Grupa: ",
,x.an,x.gru
upa);
printf("Indice materie
m (1-
-%d): ",x.n
nrd);
scanf("%d",&i);

cr
printf("\nNota: ");
scanf("%d",&n);
x.note[i]=n;
RescriePozitia(ff,dim,&x,nr
rm);
}
printf("\nNumar maatricol: ")
);

}
}
p
}
scanf("%d",&nrm);

fclose(f);

printf("\nA
_
_getch();
Apasa o tast
ta!"); lu
în
4.4.7. Fie fișierrul descris în
n exercițiul anterior.
a Scrieți un prograam C pentru exmatri-
culaarea studențiilor cu mai mult
m de 5 resttanțe.

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

pedef struct { char nu


typ ume[30];
char an
n;
int gru
upa;
În

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;
Prog
gramarea calcullatoarelor 88

d
dim=sizeof( STUDENT);

printf("\nNume fisier: ");


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

u
{ er=CitesteUrmatorul(f,dim,&x); ;
while(!er)
{ n=0;
for(i=0;i<x.nrd;i+++)

cr
if(x.note[i]<5)
n++;
if(n>5)
Sterge(f,dim,Pozzitia(f,dim
m)-1);
er=CitesteUrmatoruul(f,dim,&x
x);
}

}
}
p
printf("\nPrelucrare
fclose(f);

printf("\nA
_
_getch();
Apasa o tast
ea s-a inch

ta!");
lu
heiat");
în
4.4.8. Fie fișierrul descris în
n exercițiul 4.4.6. Scrieți un
u program C pentru mo odificarea
anuului de studiuu (se va trecee anul 1) penntru studențiii cu număruul matricol cuuprins în-
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 <conio.h>
#in
nclude "Relative.cpp"

pedef struct { char nu


typ ume[30];
char an
n;
Î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);

printf("\nNume fisier: ");


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

u
e
else
{ printf("\nPrimul nummar matrico
ol: ");
scanf("%d",&a);
er=CitestePozitia(f,,dim,a,&x);
;

cr
if(er)
printf("\nNumarul matricol %d
% nu corespunde unui student",a
a);
else
{ while((!er)&&(Poziitia(f,dim)
)<=b+1))
{ x.an=1;
f,dim,&x,Po
RescriePozitia(f ozitia(f,di
im)-1);

}
p
}
}
er=CitesteUrmato

printf("\nPrelucrare
fclose(f);

printf("\nA
orul(f,dim,

ea s-a inch

Apasa o tast
ta!");
lu
,&x);

heiat");
în
_
_getch();
}

Temee
1. Se observ vă că toate funcțiile
fu impllementate mai
m sus pentru u simula-
rea opperațiunilor de gestiune de bază folo osesc ca paraametri fișier și
ș dimen-
siune 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țio-
nale carre realizeazăă toate operațțiunile de gesstiune necesaare.
În

4.5. Simu
ularea organizării indexate a fișierelor binaree
mătoarea prooblemă: în cadrul
Fie urm c unei organizații
o d învățămînnt trebuie
de
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
Prog
gramarea calcullatoarelor 90

să realizeze
r urmmătoarele op perațiuni de gestiune:
g poppularea inițiaală a fișierullui, adău-
garrea de noi stuudenți, vizuaalizarea datellor despre unn student, vizzualizarea daatelor de-
spree 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 d la tastatură și se asigurră repetarea prelucră-
ntru toate opeerațiile datelle se preiau de
rii pînă
p la apăsaarea combinaației de taste CTRL-Z.

Pentru a simplifica gestiunea fișșierelor organnizate indexaat se pot realliza func-

u
ții care
c implem
mentează operrațiile de gesstiune de bazză. Acestea vorv 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.

cr
Fișierul Tipuri.h connține declarațțiile tipurilorr de date utiilizate atît peentru im-
mentarea operațiilor de bază
plem b cît și pentru rezolvarrea problemeelor enunțatee.

//t
tipul fisier
efine TFISIER FILE*
#de

tipul cheii
//t
pedef char TCHEIE[11];
typ

//t
;

tipul articol din tabe


ela index
lu
în
typ
pedef struct{ char is;
;
TCHEIE cheie;
c
long nr_
_rel;
} TART_IND
DEX;

tipul articol din fisi


//t ierul de da
ate
typ
pedef struct{ TCHEIE cheie;
c
char num
me[35];

int grup
pa;
int an;
e[20];
int note
} TARTICOL
L;
În

Fișierul IIndexat.cpp conține funccții care impllementează operațiile


o dee gestiune
de bază
b pentru fișierul orgaanizat indexaat și variabilee asociate unnui fișier orgaanizat in-
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>
nclude <string.h>
#in
#in
nclude "tipuri.cpp"
91 Aplicații

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

// Extindere nume prin adaugarea extensiilor


void Extinde()
{ strcpy(numei,nume);

u
strcat(numei,".idx");
strcpy(numed,nume);
strcat(numed,".dat");
}

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

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

//sortarea fisierului temporar


fseek(ind1,0,SEEK_END);
long n=ftell(ind1)/sizeof(a);
for(i=0;i<n-1;i++)
{ fseek(ind1,i*sizeof(a),SEEK_SET);
fread(&a,sizeof(a),1,ind1);
for(j=i+1;j<n;j++)
{ fseek(ind1,j*sizeof(a),SEEK_SET);
În

fread(&b,sizeof(a),1,ind1);
if(strcmp(a.cheie,b.cheie)>0)
{ 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);
Programarea calculatoarelor 92

//inlocuirea tabelei index cu fisierul sortat


remove(numei);
rename("temp.idx",numei);
ind=fopen(numei,"rb+");
}

/* Cautarea articolului cu cheia Key si plasarea pointerului de fisier


in tabela de indexuri pe articolul respectiv*/
// I - cheia cautata

u
// E - cod succes: 1 - a fost gasit articolul; 0 - nu a fost gasit arti-
colul
int SeekKey(char *Key)
{ long ls=0, ld, m, n;

cr
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;

if(strcmp(a.cheie,Key)==0)
gasit=1;
else
if(strcmp(a.cheie,Key)>0)
lu
fseek(ind,m*sizeof(a),SEEK_SET);
fread(&a,sizeof(a),1,ind);
în
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+");
În

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

// Inchiderea tabelei index


// I -
// E -
void Close_index()
{ fclose(ind);
fclose(f);
}

u
// 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 ar-
ticol

cr
int ReadSec(TARTICOL *a)
{ TART_INDEX a1;
int r;
fread(&a1,sizeof(a1),1,ind);
if(feof(ind))
r=0;

}
else

}
r=1;

return r;
lu
{ fseek(f,a1.nr_rel*sizeof(*a),SEEK_SET);
fread(a,sizeof(*a),1,f);
în
// 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 ar-
ticol
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;
}
În

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;
Programarea calculatoarelor 94

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

if(n>0)
{ fseek(ind,(n-1)*sizeof(a1),SEEK_SET);
fread(&a1,sizeof(a1),1,ind);

u
if(strcmp(a1.cheie,a.cheie)>=0) r1=0;
else r1=1;
}
if((n==0)||(r1==1))

cr
{ 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);

}
}
r=1;

return r; lu
fwrite(&ai,sizeof(ai),1,ind);
fwrite(&a,sizeof(a),1,f);
în
//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);
În

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

// 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);

u
fread(&a1,sizeof(a1),1,ind);
if(feof(ind))
r=0;
else

cr
{ fseek(ind,pos,SEEK_SET);
a1.is=0;
fwrite(&a1,sizeof(a1),1,ind);
Sort();
r=1;
}

}
return r;

lu
// 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)
în
{ 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)
În

{ 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;
}
Prog
gramarea calcullatoarelor 96

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

4.5.1. Popularrea inițială a fișierului se realizează prin p adăugareea repetată dee înregis-
trărri, după crearrea unui fișieer nou. La addăugarea de noin studenți singura diferrență față

u
de popularea
p innițială este căă lucrează cuu un fișier ex
xistent. Ca urrmare, cele două
d pro-
blem me de preluccrare pot fi reezolvate cu aacelași progrram: dacă fișșierul de datee nu exis-
tă, va
v fi întîi creeat. În mod normal,
n la poopularea inițială a fișieruului datele see introduc

cr
în ordinea
o cresccătoare a cheeilor, deci see folosește operația de addăugare în accesa sec-
vennț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.

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

id main()
voi
lu
în
{ 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();
}

// 4.5.1.a. POPULARE / ADAUGARE


A in
n acces dir
rect
În

printf("\nA
p Adaugarea in rect dupa cheie\n");
n acces dir
p
printf("\nC od matricol
l: ");
f
fflush(stdi n);
g
gets(x.chei e);
w
while(!feof (stdin))
{ printf("Nume si prennume: ");
fflush(stdin);
gets(x.nume);
printf("Grupa: ");
scanf("%d",&x.grupa));
97 Aplicații

printf("AAn: ");
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<n;i++)
{ printf("Nota %2d: ",i);
e[i]);
scanf("%d",&x.note

u
}
if(WriteKey(x))
ul a fost adaugat\n")
printf("\nArticolu a ;
else printf("\nCheie
e invalida\
\n");

cr
getch();
printf("\nCod matric
col: ");
fflush(stdin);
gets(x.cheie);
}

}
C
Close_index

printf("\nA
p
g
getch();
();

Apasa o tast
ta");

lu
în
#in
nclude "indexat.cpp"
nclude <conio.h>
#in
#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( );
În

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

// 4.5.1.b. POPULARE / ADAUGARE


A in
n acces secvential

printf("\nA
p Adaugarea inn acces dir
rect dupa cheie\n");
p
printf("\nC od matricol
l: ");
f
fflush(stdi n);
Prog
gramarea calcullatoarelor 98

gets(x.cheie);
g
w
while(!feof (stdin))
{ printf("Nume si pren
nume: ");
fflush(stdin);
gets(x.nume);
printf("Grupa: ");
scanf("%d",&x.grupa)
);
printf("AAn: ");
scanf("%d",&x.an);

u
for(i=0;i<20;i++)
x.note[i]=0;
printf("Numar note (maxim 20):
: ");
scanf("%d",&n);

cr
for(i=0;i<n;i++)
{ printf("Nota %2d: ",i);
e[i]);
scanf("%d",&x.note
}
if(WriteSec(x))
ul a fost adaugat\n")
printf("\nArticolu a ;

}
C
else printf("\nCheie
getch();

fflush(stdin);
gets(x.cheie);

Close_index ();
e invalida\

printf("\nCod matric
col: ");

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

4.5.2. Vizualiizarea tuturorr datelor din fișier: se va genera o listtă într-un fișiier text.

#in
nclude "indexat.cpp"
nclude <conio.h>
#in
#in
nclude <stdlib.h>
În

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;
}

TFISIER g;
T
g
g=fopen("Cu rsanti.txt"
","w");
r
rewind(ind) ;
f
fprintf(g," \n%20c List
ta cursanti
ilor inregi
istrati\n\n",' ');
f
fprintf(g," \n%-10s %-3
35s Grupa An
A Note\n","Cod matr.","Nume si prenu-
me"
");

u
R
ReadSec(&x) ;
w
while(!feof (ind))
{ fprintf(g,"\n%10s %335s %5d %2d
d ",x.cheie
e, x.nume, x.grupa,
x x.
.an);
for(i=0;(i<20)&&(x.nnote[i]);i+
++)

cr
fprintf(g,"%2d ",xx.note[i]);
;
ReadSec(&&x);
}
f
fclose(g);
p
printf("\nL ntilor se afla
ista cursan a in fisierul Cursa
anti.txt");
;
C
Close_index ();

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

lu
4.5.3. Vizualiizarea datelor despre un student: studdentul este iddentificat pe baza co-
în
dului matricol introdus de laa tastatură.

#in
nclude "indexat.cpp"
nclude <conio.h>
#in
#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);
În

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: ");
Prog
gramarea calcullatoarelor 100

gets(c);
g
w
while(!feof (stdin))
{ if(SeekKey(c))
{ ReadSec(&x);
printf("\nAm gasitt studentull:\n");
printf("\nNume : %-355s",x.nume);
printf("\nCod matrricol: %-100s",x.cheie
e);
printf("\nAn si grrupa : %2d / %4d",x.an,x.grupa);
printf("\nNote : ");

u
for(i=0;(i<20)&&(xx.note[i]);;i++)
printf("%2d ",x.note[i]);
printf("\n");
}

cr
else
printf("\nNu e inrregistrat un
u cursant cu acest co
od matricol
l.\n");
printf("\n\nCod matrricol: ");
gets(c);
}
C
Close_index ();

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

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

#in
nclude "indexat.cpp"
nclude <conio.h>
#in
#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);
În

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

char num[20];
c
p
printf("\nG rupa: ");
s
scanf("%d", &gr);
w
while(!feof (stdin))
{ sprintf(num,"%d.txt"",gr);
g=fopen(num,"w");
rewind(ind);
fprintf(g,"\n%20c Liista cursan
ntilor inre
egistrati pe
entru grupa
a
\n\n",' ',gr);
%d\

u
fprintf(g,"\n%-10s %-35s
% An No
ote\n","Cod matr.","Nume si pren
nume");
ReadSec(&&x);
while(!feof(ind))
{ if(x.grupa==gr)

cr
{ fprintf(g,"\n%100s %35s %2d
d ",x.cheie
e, x.nume, x.an);
x
for(i=0;(i<20)&&&(x.note[i]
]);i++)
fprintf(g,"%2dd ",x.note[
[i]);
}
ReadSec(&x);
}

%s"

}
C
fclose(g);
printf("\nLista curs
",gr,num);
printf("\nGrupa: ");
scanf("%d",&gr);

Close_index ();
santilor gr

;
lu e afla in fisierul
rupei %d se
în
printf("\nA
p Apasa o tast
ta");
g
getch();
}

4.5.5. Înscrierrea unei notee pentru un student: stuudentul este identificat


i prin inter-
meddiul codului matricol. No
ota va fi adăuugată la sfîrșșitul vectorullui de note, dacă
d nu s-

a deepășit lungim
mea maximă..

#in
nclude "indexat.cpp"
#in
nclude <conio.h>
În

#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();
Prog
gramarea calcullatoarelor 102

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

TCHEIE c;
T
i
int nr;
p
printf("\nC od matricol
l: ");

u
g
gets(c);
w
while(!feof (stdin))
{ if(SeekKey(c))
{ ReadSec(&x);

cr
printf("\nAm gasitt studentull:\n");
printf("\nNume : %-355s",x.nume);
printf("\nAn si grrupa : %2d / %4d",x.an,x.grupa);
printf("\nNote : ");
for(i=0;(i<20)&&(xx.note[i]);;i++)
printf("%2d ",x.note[i]);
if(i<20)
{ printf("\nNoua nota:

}
RewriteKey(x);

else
n
scanf("%d",&x.no
");
ote[i]);

daugat nota
printf("\nS-a ad lu
a");
în
printf("\nStuden
ntul are deeja destule
e note");
printf("\n");
}
else
printf("\nNu e inrregistrat un
u cursant cu acest co
od matricol
l.\n");
printf("\n\nCod matrricol: ");
gets(c);

}
C
Close_index ();

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

4.5.6. Înscrierrea notelor pentru


p o gruppă de studențți: de la tastaatură se intro
oduce nu-
mă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"
nclude <conio.h>
#in
103 Aplicații

#include <stdlib.h>

void main()
{ int i,n;

printf("\nNumele fisierului indexat:");


fflush(stdin);
gets(nume);

u
Extinde();
Open_index();
if(f==NULL)
{ printf("\nFisierul poate fi deschis");

cr
return;
}

int gr;
printf("\nGrupa: ");
scanf("%d",&gr);
while(!feof(stdin))
{ rewind(ind);
ReadSec(&x);
while(!feof(ind))
{ if(x.grupa==gr) lu
{ printf("\nAm gasit studentul:\n");
printf("\nNume : %-35s",x.nume);
în
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");
În

}
ReadSec(&x);
}
printf("\nGrupa: ");
scanf("%d",&gr);
}
Close_index();

printf("\nApasa o tasta");
getch();
Prog
gramarea calcullatoarelor 104

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

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

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

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

lu
g
gets(nume);

Extinde();
E
O
Open_index( );
i
if(f==NULL)
{ printf("\nFisierul poate
p fi de
eschis");
return;
}
în
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);
printf("\nAm gasitt studentull:\n");
printf("\nNume : %-355s",x.nume);
printf("\nAn si grrupa : %2d / %4d",x.an,x.grupa);
printf("\nNote : ");
for(i=0;(i<20)&&(xx.note[i]);;i++)
În

printf("%2d ",x.note[i]);
printf("\nConfirmaati stergerrea? (D / N):
N ");
r=getch();
if((r=='D')||(r=='d'))
{ DeleteKey(c);
printf("\nCursan
ntul a fostt eliminat");
}
else
printf("\nAnular
re, cursanttul ramine inregistrat
t");
printf("\n");
105
5 Aplicații

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

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

u
g
getch();
}

Temee

cr
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.
2. Scrieți programul care realizeazză operațiuneea de transfeerare a tuturoor studen-
ților dinntr-o grupă către
c o altă grrupă.
3. Enunțațți o problem mă de gestiunne a datelor care să se preteze
p la org
ganizarea

4.

5.
indexattă a acestora..
Scrieți un program

lu
m multifuncțiional care săă realizeze toate
gestiune pentru probblema enunțaată anterior.
t operațțiunile de

Proiectaați o modalittate mai bunnă (mai geneerală) de impplementare a operații-


lor de ggestiune de bază,
b
Sugestiie: folosiți modelul
m
eliminînd restricțiile incluse în exemplul dee mai sus.
de simulare a orgganizării relaative din sub
bcapitolul
în
anteriorr și tema 1 diin același subbcapitol.

În

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