Documente Academic
Documente Profesional
Documente Cultură
Managementul fiierelor n C
Prin fiier se nelege o colecie de date, pstrat pe un dispozitiv periferic, care de regul
este un disc magnetic sau optic. Aceast colecie de date poate fi interpretat ca i o succesiune de
caractere, de cuvinte, linii sau pagini ale unui document de tip text, ca i cmpuri sau nregistrri
ale unei baze de date sau de exemplu, ca i pixelii unei imagini grafice.
Toate fiierele, indiferent de tipul de date pe care le conin sau de metodele folosite pentru
procesarea acestor date au cteva proprieti importante. Astfel, acestea trebuie deschise pentru
citire i trebuie nchise la ncheierea prelucrrii lor, n aceste fiiere se pot scrie date, pot fi
adugate date sau pot fi citite date din ele. Cnd un fiier este deschis, datele sale pot fi accesate
de la nceputul sau de la sfritul fiierului sau dintr-un loc oarecare din fiier. Pentru prevenirea
folosirii necorespunztoare a unui fiier, sistemul de operare instalat pe calculator trebuie s fie
ntiinat despre scopul n care este deschis fiierul i despre operaiile care vor fi efectuate (citire,
scriere, adugare) asupra datelor. La ncheierea operaiunilor care se efectueaz asupra datelor
dintr-un fiier acesta trebuie nchis deoarece n caz contrar, sistemul de operare nu poate actualiza
datele referitoare la acel fiier (dimensiune, data ultimei accesri, etc.).
Exist dou tipuri de fiiere cu care se poate opera ntr-un program: fiiere text i fiiere
binare. Fiierele text stocheaz datele ca o secven de caractere alfanumerice i coninutul acestor
fiiere este lizibil i poate fi editat direct cu ajutorul unui editor de texte.
Aceste fiiere text sunt organizate pe rnduri, fiecare rnd fiind delimitat de caracterul de sfrit de
rnd EOL.
Deoarece fiierele text sunt citite caracter cu caracter, funciile pentru citirea i scrierea lor vor fi
aproape identice cu cele folosite pentru citirea de la tastatur i respectiv scrierea pe monitor.
Din cauza procesrii secveniale, un fiier text se deschide de obicei numai pentru un anumit tip de
operaie la un moment dat (citire, scriere sau adugare).
Fiierele binare pot s conin orice tip de date, codate ntr-o form binar, n secvene de bytes.
Pentru aceste fiiere nu exist caracter special de sfrit de fiier i ele pot conine orice fel de
informaie : text formatat, imagini, sunete,
Din punctul de vedere al sistemului de operare, fiierele binare nu sunt diferite de fiierele text. Mai
mult, n limbajul C un byte este echivalent cu un caracter, astfel c un fiier binar este de
asemenea vzut ca un stream de caractere. Totui, fiierele binare difer de fiierele text n dou
puncte eseniale. Pe de o parte, admind c fiierele binare conin date care nu sunt neaprat
interpretabile ca i text, fiecare octet de date este transferat pe sau de pe disc neprocesat. n al
doilea rnd, interpretarea fiierelor binare este lsat pe seama programatorului, acestea putnd fi
citite sau scrise n orice mod dorit de ctre programator.
Fiierele binare pot fi procesate secvenial sau, n funcie de necesitile aplicaiei, acestea pot fi
procesate folosind tehnici de accesare aleatoare a nregistrrilor pe care le conin. Aceast
procesare aleatoare implic poziionarea ntr-un anumit loc din fiier, nainte de citirea sau scrierea
datelor, astfel c aceste fiiere sunt n general procesate prin operaii de citire/scriere simultane.
Astfel, se poate face poziionarea instantanee pe orice structur din fiier i de asemenea poate fi
modificat coninutul unei structuri oriunde n fiier, n orice moment de timp.
Fiierele binare sunt accesate mai rapid dect fiierele text i sunt nelese numai de programe
scrise special s lucreze cu astfel de fiere. Bazele de date, de exemplu, sunt create i procesate
ca i fiiere binare.
Spre exemplu, o valoare ntreag, s zicem 123, este stocat ntr-un fiier text ca un ir de
trei caractere, '1', '2' i '3'. Aceasa face ca respectiva valoare s fie citit cu uurin ntr-un editor
de texte dar, pe de alt parte, aceast reprezentare a ei este ineficient deoarece sunt necesari 3
octei pentru stocarea ei, cte unul pentru fiecare caracter.
Intr-un fiier binar, aceast valoare ntreag poate fi stocat pe un singur byte (12310=11110112);
n consecin, fiierele binare ofer un mod de stocare mult mai compact a valorilor numerice, dar
au i dezavantajul c nu pot fi vizualizate direct, ca i fiierele de tip text.
n fiierele binare, informaia este stocat exact ca i n memoria calculatoarelor, iar acest lucru
face ca transferul coninutului variabilelor C s se fac direct ntre memoria computerelor i aceste
fiiere binare.
1
Curs 8
Un alt aspect asupra cruia trebuie s insistm este faptul c fiierele binare conin pur i
simplu serii de octei i nu rein n nici un fel tipul de informaie stocat n acestea. Aadar,
programatorul trebuie s fie foarte atent la scrierea i citirea datelor care vor fi atribuite variabilelor
programului. Acest lucru este n particular important atunci cnd fiierele binare vor fi folosite de
ctre alte programme sau pe maini de calcul diferite care stocheaz pe un numr diferit de octei
date cu acelai tip (de exemplu ntregii pot fi stocai pe 4 (Unix) sau pe 2 octei (PC-uri Intel)).
Operaiile efectuate asupra fiierelor binare sunt similare cu cele efectuate asupra fiierelor
text deoarece ambele tipuri sunt considerate ca stream-uri de octei. n limbajul C, aceleai tipuri
de funcii sunt folosite pentru procesarea celor dou tipuri de fiiere. Totui, funciile pentru
managementul fiierelor binare sunt puin mai pretenioase dar pe de alt parte conduc la
citiri/scrieri mai rapide.
Operaiile specifice fiierelor se realizeaz cu funcii standard existente n biblioteca limbajului,
avnd prototipurile n fiierul <stdio.h>. Aceste operaii sunt: deschidere, nchidere, creare,
citirea datelor, adugarea de nregistrri, poziionarea pe o anumit nregistrare i tergerea
fiierelor.
Pentru ca un fiier s poat fi folosit ntr-un program C acesta trebuie declarat.
Declararea fiierelor
Declararea fiierelor se face sub forma:
FILE *df;
unde FILE este un cuvnt cheie care semnific o structur de date de tip fiier, iar df este numit
descriptor de fiier i reprezint un pointer spre tipul FILE.
Exemple
FILE *f1, *fin, *frez;
Deschiderea fiierelor
Pentru a putea avea acces la datele dintr-un fiier, acesta trebuie deschis. Deschiderea unui fiier
se face folosind funcia fopen, care are prototipul:
FILE *fopen(const char *cale, const char *mod);
unde cale este un pointer spre un ir de caractere care definete calea spre fiierul care se
deschide, iar mod este un pointer spre un ir de caractere care definete modul de prelucrare a
fiierului dup deschiderea acestuia.
Concret, cale reprezint orice nume valid de fiier, eventual precedat de calea de directoare pn
la acesta, cuprins ntre ghilimele. Dac trebuie specificat calea pn la respectivul fiier, atunci
directoarele cii vor fi separate prin \\ ca de exemplu: "d:\\BC\\input.txt".
Cel de-al doilea parametru al funciei fopen, mod, este atributul fiierului i poate fi scris numai cu
caractere mici, putnd avea valorile:
"r"
caz n care fiierul se deschide pentru citire
"w"
caz n care fiierul se deschide pentru scriere
"a"
caz n care fiierul se deschide pentru adugare de nregistrri
"r+" caz n care fiierul se deschide pentru citire i scriere
"rb" caz n care fiierul se deschide pentru citire binar
"wb" caz n care fiierul se deschide pentru scriere binar
"r+b" caz n care fiierul se deschide pentru citire i scriere binar
Un fiier inexistent, deschis n modul "w" va fi creat (dac este posibil) n momentul
deschiderii, iar un fiier existent deschis n modul "w" va fi creat din nou, ceea ce nseamn c
vechiul su coninut se va terge.
Deschiderea n modul "w" va eua dac sistemul nu poate deschide fiierul i acest lucru se poate
ntmpla atunci cnd discul este plin, cnd este protejat la scriere sau atunci cnd pe un sistem cu
fiiere partajate, respectivul fiier este folosit de ctre un utilizator care nu are drepturi de accesare
a respectivului fiier.
2
Curs 8
Deschiderea n modul "r" eueaz atunci cnd fiierul nu exist sau dac fiierul este protejat ntrun anume fel i este interzis accesul la respectivul fiier.
Unui fiier inexistent deschis n modul "r" i se va asocia pointerul NULL.
Dac deschiderea se face cu succes, funcia fopen returneaz un pointer la fiierul deschis, iar n
caz contrar returneaz pointerul NULL.
La deschiderea n modul "a", dac fiierul exist, poziionarea se face la sfritul fiierului, iar dac
nu exist atunci el va fi creat. Deschiderea n modul "a" poate eua n aceleai cazuri n care
eueaz deschiderea n modul "w".
Observaie
Pentru modurile actualizare, pentru care este permis att operaia de citire ct i cea de scriere
(modurile care includ semnul +), pentru evitarea unor comportri aleatorii, ntre o citire i o scriere
sau ntre o scriere i o citire, streamul de fiier va trebui curat (cu funcia fflush) sau va trebui
fcut repoziionarea n acesta, folosind funciile fseek, rewind sau fsetpos.
Exemple
FILE *f, *fin;
f=fopen("notean1.dat","r");
/* se deschide fisierul notean1.dat, din directorul curent,
modul citire.*/
fin=fopen("c:\\soft\\config.ini","w");
// se deschide fisierul c:\soft\config.ini in modul scriere.
in
Faptul c n caz de eroare funcia fopen returneaz pointerul NULL poate fi folosit pentru testarea
posibilitii deschiderii unui fiier, sub forma:
Exemplu
if((f=fopen("fis_test","r"))==NULL)
printf("Eroare la deschiderea fisierului!");
sau :
f=fopen("fis_test","r");
if(!f)
printf("Eroare la deschiderea fisierului!");
nchiderea fiierelor
Dup terminarea procesrii unui fiier, acesta trebuie nchis. nchiderea fiierelor se face cu funcia
fclose, al crui prototip este:
int fclose(FILE *pf);
unde pf este pointerul spre tipul FILE i valoarea lui a fost determinat de ctre funcia fopen la
deschiderea fiierului. Funcia fclose returneaz valoarea 0 la nchidere reuit i valoarea -1 n
caz de eroare.
Exemplu
1. fclose(fin);
2. // Testarea nchiderii reusite a unui fisier
// se poate intampla atunci cand pointerul fin nu a fost initializat
if(fclose(fin)) //sau: if(fclose(fin)!=0)
{
printf("Fisierul nu exista ! ");
exit(0);
}
Curs 8
Exemple
FILE *fin, *fout;
fin=fopen("test.inp","r");
fout=fopen("test.out","w");
...
fscanf(fin,"%d",&n);
fprintf(fout,"n^2= %d",n*n);
...
Exemplu
FILE *fp;
int ch='a';
fp=fopen("test.txt","w");
fputc(ch,fp);
Funciile fgetc i fputc returneaz caracterul citit sau scris n caz de succes i EOF n caz de
eroare. EOF este un caracter constant care indic sfritul de fiier. Testarea citirii acestui caracter
se face folosind funcia feof(f), unde parametrul funciei este un pointer la tipul FILE. Funcia
feof returneaz o valoare nenul dac a fost detectat caracterul EOF i zero dac nu a fost citit
caracterul EOF.
4
Curs 8
Funciile fgets i fputs sunt folosite pentru preluarea ntr-un ir, respectiv scrierea ntrun ir a unor caractere dintr-un/ntr-un fiier (stream). Prototipurile lor sunt:
char *fgets(char *s, int n, FILE *stream);
int fputs(const char *s, FILE *stream);
Funcia fgets preia ntr-un ir n-1 caractere dintr-un fiier i returneaz irul la care pointeaz s,
respectiv pointerul NULL n caz de eroarea sau la ntlnirea caracterului de sfrit de fiier. Funcia
fputs scrie un ir de caractere ntr-un fiier i returneaz ultimul caracter scris, respectiv EOF n
caz de eroare.
Exemple
1. //Citirea unui rand dintr-un fisier
char sir[100];
FILE *f;
f=fopen("d:\\test.inp","r");
fgets(sir,100,f);
printf("Sirul citit este: %s",sir);
fclose(f);
2. // Tiparirea la imprimanta (functioneaza pentru o imprimanta
// conectata la portul LPT1
FILE = *prt;
if((prt=fopen("LPT1","w"))==NULL)
{
printf("\a\nPrinter nedisponibil");
exit(0);
}
else
fprintf(prt,"Test tiparire la imprimanta!");
Poziionarea ntr-un fiier
Pentru cunoaterea poziiei capului de citire/scriere al unui fiier i pentru poziionarea ntrun anumit loc din fiier se folosesc funciile ftell i respectiv fseek.
Funcia ftell determin poziia curent a capului de citire/scriere i are prototipul:
long ftell(FILE *pf)
Funcia returneaz o valoare care reprezint deplasamentul n octei al poziiei capului de
citire/scriere fa de nceputul fiierului.
Pentru poziionarea ntr-un anumit loc dintr-un fiier se folosete funcia fseek.
Poziionarea aleatoare ntr-un fiier permite accesarea aleatoare a datelor din fiierul respectiv.
Prototipul funciei este:
int fseek(FILE *pf, long deplasament, int origine);
unde pf este un pointer spre tipul FILE i definete fiierul n care se face poziionarea capului de
citire/scriere, iar valoarea acestui pointer este determinat la deschiderea fiierului.
Deplasament definete numrul de octei peste care se va deplasa capul de citire/scriere al discului
i poate fi o valoare ntreag pozitiv sau negativ. Desigur, aceast valoare nu poate fi negativ
dac deplasarea se face de la nceputul fiierului dar pe de alt parte trebuie s fie negativ dac
deplasarea se face de la sfritul fiierului.
Origine determin locul din care se face deplasarea capului i poate avea valorile 0, 1 sau 2,
acestea nsemnnd c deplasarea se face de la nceputul fiierului, de la poziia curent a capului
de citire/scriere, respectiv de la sfritul fiierului. Funcia fseek returneaz 0 n caz de succes,
adic n caz de poziionare corect a cursorului n fiier.
5
Curs 8
Exerciiu
Scriei un program care s citeasc un fiier text, caracter cu caracter i s-l tipreasc pe ecran.
Folosii macrourile getch() i putchar(). Testai existena fisierului.
Program exemplu: determinarea numrului de caractere dintr-un fiier (se numr i caracterele de
rnd nou)
#include <stdio.h>
#include <stdlib.h>
int main( )
{
FILE *fp;
char c;
int n=0;
/*Se deschide fisierul de intrare, testandu-se deschiderea corecta a acestuia.
Daca deschiderea fisierului nu se poate realiza (fisier inexistent) functia
fopen returneaza pointerul NULL*/
if((fp = fopen("d:\\flinii.txt","r"))==NULL)
6
Curs 8
{
printf("Eroare la deschiderea fisierului!");
exit(1);
}
while(fscanf(fp,"%c",&c)==1)
{
n++;
}
fclose(fp);
printf("In fisier sunt %d caractere.",n);
return 0;
}
Exerciiu
Modificai programul de mai sus astfel nct caracterele de rnd nou s nu fie numrate.
Deoarece deschiderea unui fiier existent n modul "w" implic suprascrierea acestuia, este
recomandabil ca n astfel de situaii utilizatorul s fie atenionat asupra acestui lucru. Dm mai jos
un exemplu de program care testeaz existena unui fiier care se deschide n modul "w".
Program exemplu: interogarea utilizatorului n cazul suprascrierii unui fiier deschis n modul "w".
Curs 8
#include<stdio.h>
#include<conio.h>
int main()
{
FILE *fout;
char nfout[20] ;
char opt;
int OK;
do
{
printf("\nIntroduceti numele fisierului de iesire: " );
gets(nfout) ;
fout=fopen(nfout,"r") ;
if(fout!=NULL)
{
fclose(fout);
printf("\aFisierul exista! \nSuprascrieti acest fisier? (D/N): ");
opt=getche();
switch(opt)
{
case 'D':
{
OK=1;
fout=fopen(nfout,"w");
8
Curs 8
}
while((OK!=1)&&fout);
if(opt=='D')
fprintf(fout,"Suprascriere in fisier!");
else
fprintf(fout,"Scriere in fisier!");
printf("\nTerminat!");
fclose(fout);
return 0;
}
Program exemplu: folosirea funciei fgets pentru tiprirea unui fiier pe ecran
#include<stdio.h>
int main()
{
char *c, rand[100],nf[25];
FILE *f;
printf("Introduceti numele fisierului: ");
scanf("%s",nf);
f=fopen(nf,"r");
do
{
c=fgets(rand,100,f); //functia fgets returneaza sirul la care pointeaza
//pointerul rand.
if(c)
printf("%s",rand);
}
while(c);
fclose(f);
return 0;
}
Curs 8
struct bd ag;
char sir[20];
int *pi,*pu;
if((fin=fopen("c:\\temp\\bd.dat","wb"))==NULL)
{
printf("Eroare la deschiderea fisierului!");
exit(1);
}
strcpy(ag.n,"Popescu");
strcpy(ag.p,"Georgel");
strcpy(ag.tel,"0445111222");
ag.v=40;
ag.s=1;
fwrite(&ag,sizeof(ag),1,fin);
fclose(fin);
fin=fopen("c:\\temp\\bd.dat","rb");
fseek(fin,0,0);
printf("Datele din fisier:\n\n");
fread(sir,sizeof(ag.n),1,fin);
printf("NUME: \t\t%s\n",sir);
fread(sir,sizeof(ag.p),1,fin);
printf("PRENUME: \t%s\n",sir);
fread(sir,sizeof(ag.tel),1,fin);
printf("Telefon: \t%s\n",sir);
fread(pi,sizeof(ag.v),1,fin);
printf("Varsta: \t%d\n",*pi);
fread(pu,sizeof(ag.s),1,fin);
printf("Stare civila: \t%d\n",*pu);
return 0;
}
Dup rularea acestui program se obine fiierul bd.dat n directorul d:\c. Deschiznd fiierul bd.dat
cu un utilitar de gestiune a fiierelor, acesta va arta sub forma:
Pe ecran, va fi tiprit:
Curs 8
Pentru a rula programul acesta trebuie compilat, obinndu-se codul executabil. Apoi, executabilul
se lanseaz n execuie ntr-o fereastr DOS (Start -> Run -> cmd) sub forma:
Mai jos este dat ca exemplu un program care s adune dou numere, cu cele dou numere date
n linia de comand.
11
Curs 8
Exemple de output ale acestui program, n funcie de numrul de parametri cu care a fost apelat
sunt date mai jos:
apel1:
output 1:
apel 2:
output 2:
apel 3:
output 3:
Program exemplu: calculul coordonatelor centrului de mas al unui sistem de particule ale cror
date se gsesc ntr-un fiier
12
Curs 8
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
FILE *fin,*fout;
float m,x,y,z,sm,smx,smy,smz,xc,yc,zc;
int i;
char opt;
void scrie_date()
{
fout=fopen("d:\\bc\\centru.rez","w");
fprintf(fout,"Nr. particule: %d",i);
fprintf(fout,"\nsm= %g \nsmx= %g smy= %g smz= %g ",sm,smx,smy,smz);
fprintf(fout,"\nxc= %g\t yc=%g\t zc=%g\n",xc,yc,zc);
fclose(fout);
}
int main()
{
sm=smx=smy=smz=0;
i=0;
if((fin=fopen("d:\\bc\\centru.dat","r"))==NULL)
{
printf("\nFisierul nu poate fi deschis\a\a\a");
}
while(!feof(fin))
{
if(fscanf(fin,"%f%f%f%f",&m,&x,&y,&z)==4)
{
sm+=m; smx+=m*x; smy+=m*y; smz+=m*z;
i++;
}
}
xc=smx/sm;
yc=smy/sm;
zc=smz/sm;
fclose(fin);
if((fout=fopen("d:\\bc\\centru.rez","r"))!=NULL)
{
printf("\nAtentie! Fisierul de output exista!");
printf("\nCONTINUATI ? (Y/N)");
opt=getch();
fclose(fout);
if((opt=='y')||(opt=='Y') )
scrie_date();
else
{
printf("\nExecutie terminata!");
exit(1);
}
}
else
scrie_date();
printf("\nTerminat!");
return 0;
}
Bibliografie suplimentar
http://www.codingunit.com/c-tutorial-binary-file-io
13