Sunteți pe pagina 1din 7

Udritoiu tefan

Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere

Lucrarea 4 Lucrul cu Fiiere.


Ce este un fiier i la ce poate folosi el?
Atunci cnd dorim s memorm informaii putem s le pstram n memorie. Singurul
dezavantaj este acela c atunci cnd nchidem programul toate informaiile se vor pierde.
Alternativa ar fi pstrarea lor pe un suport extern (hard-disk), n fiiere.
Pentru a putea folosi fiiere, avem nevoie s avem posibilitatea s efectum cteva
funcii: citire din fiier, scriere n fiier, regsire informaii.
Fiecare fiier care este folosit trebuie deschis n mod explicit nainte ca programul s
poat citi sau scrie n el. Un fiier se deschide folosind funcia fopen ( ). Ea primete ca
parametri numele fiierului (respectiv calea), modalitatea de deschidere, i va returna un
pointer care va fi folosit n continuare pentru executarea operaiilor I/O. Acest pointer este de
tipul FILE, care este definit n stdio.h.
Declaraia variabilei fiier se face astfel:
FILE

*fiier;

Deschiderea i nchiderea unui fiier


Funcia care deschide un fiier este fopen( ). Exemplu:
fisier = fopen (nume.extensie,r);

Variabilei de tipul FILE, fiier i se asociaz un pointer ctre fiierul de deschis cu


numele nume.extensie, pointer returnat de funcia fopen( ). Fiind un fiier folosit doar de o
anumit aplicaie, el poate avea orice nume i extensie dorii. Nu conteaz c are extensia .dat
sau .ion ci conteaz modul de scriere i citire din el.
r semnific faptul c fiierul este deschis pentru citire. Acest argument se numete
mod. n C exist mai multe moduri n care un fiier poate fi deschis, n funcie de scopul
pentru care dorim s l folosim: citire, scriere, citire i scriere.
Urmtorul tabel prezint modurile n care un fiier poate fi deschis:
Argument

Descriere

Deschide un fiier text pentru citire.

Creeaz un fiier text pentru scriere. Dac acesta exist, este suprascris.

Deschide un fiier text n modul adugare. Textul este adugat la sfritul


fiierului.

rb

Deschide un fiier binar pentru citire.

wb

Creeaz un fiier binar pentru scriere. Dac acesta exist, este suprascris.

ab

Deschide un fiier binar n modul adugare. Data este adugat la sfritul


fiierului.

r+

Deschide un fiier text pentru citire i scriere.

1
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere
w+

Creeaz un fiier nou pentru citire i scriere. Dac fiierul exist, este
suprascris.

a+

Deschide un fiier text pentru citire i scriere, la sfrit.

r+b or rb+ Deschide un fiier binar pentru citire i scriere.


w+b or
wb+

Creeaz un fiier binar pentru citire i scriere. Dac fiierul exist, este
suprascris.

a+b or ab+ Deschide un fiier binar pentru citire i scriere, la sfrit.


ncercarea de a face operaii cu fiierul n plus fa de ceea ce ne permite modul n care
acesta a fost deschis, va genera o eroare din partea mediului de programare.
n practic funcia fopen( ) este de cele mai multe ori inclus ntr-un if:
if ((fisier = fopen("nume.extensie", "rb")) == NULL)
fprintf(stderr,"fisierul %s nu poate fi deschis","nume.extensie");

Prin aceasta se verific dac fopen a reuit s deschid fiierul, n caz contrar
returnnd NULL. Pentru a evita eroarea care ar urma s fie generat de program mai departe,
cnd ar ncerca s foloseasc acel fiier nedeschis, se poate apela funcia de terminare
program:
if ((fisier = fopen("fisier.extensie", "rb")) == NULL) {
fprintf(stderr,"fisierul %s nu poate fi deschis","nume.extensie");
exit(1);
}

Dup ce s-a ncheiat lucrul cu fiierul, acesta va trebui nchis, folosind funcia close().
De abia dup aceea va putea fi eventual redeschis pentru un alt scop (de exemplu era deschis
pentru citire, si se dorete redeschiderea lui pentru scriere). Funcia are sintaxa:
fclose (fisier);

Dup apelul aceste funcii, nu se mai pot efectua nici un fel de operaii asupra
fiierului, pn la o nou deschidere.

Citirea din fiier


Citirea dintr-un fiier se execut cu funcia fread( ). Ea primete ca parametri
variabila n care se face citirea, dimensiunea n octei ct se citete i pointerul la fiierul din
care se citete. Sintaxa este:
fread(&pret,sizeof(pret),1,fisier);

unde: pre este variabila n care se citete i care poate fi de oricare din tipurile
predefinite sau definite de utilizator din C. Astfel nct nu conteaz c pre este de tipul int,
double sau c este o structur definit de utilizator.
Observm c nu trebuie s specificm noi neaprat dimensiunea, mai ales c este
posibil s nu o tim exact. Ea este returnat de funcia sizeof( ). Fiier reprezint pointerul
ctre fiierul de utilizat, descris mai sus.

2
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere

Atunci cnd dm comanda fread( ), se va citi din fiier din poziia curent a cursorului
care iniial, atunci cnd se deschide fiierul este chiar la nceput. Dup prima citire, cursorul
se va afla poziionat dup primii sizeof(pret) octei, deci nainte de cea de-a doua nregistrare.
Problema este ce facem atunci cnd dorim s citim nregistrarea a 3, de exemplu.
Am putea de exemplu s apelm de 3 ori funcia fread( ). Acest lucru nu este totui
posibil dac dorim s citim o nregistrare care se afl la sfirtul fiierului.
O alt variant este folosirea funciei seek( ). Ea are sintaxa:
fseek (fisier, pozitie, origine );

Aceast funcie va poziiona cursorul n fiierul fisier, dup pozitie octei,


ncepnd cu poziia precizat de origine. Deci practic va sri peste poziie octei
ncepnd din origine.
Originea poate fi: nceputul fiierului (origine = SEEK_SET), poziia curent a
pointerului n fiier(SEEK_CUR), sau sfritul fiierului (SEEK_END).
fseek (fisier, 5*sizeof(pret), SEEK_SET);

Dac dorim s citim fiecare nregistrare pe rnd va trebui s ne poziionm la


nceputul fiierului (cum?) i apoi s citim pn se ajunge la sfrit. Funcia care ne
avertizeaz c s-a ajuns la sfritul fiierului este feof( ). Ea va returna true atunci cnd s-a
ajuns la sfrit i nu se mai poate face nici o citire. Exemplu:
while (! feof (fisier))
fread(&pret, sizeof(pret), 1, fisier);

Scrierea n fiier
Pentru a putea scrie n fiier acesta trebuie n primul rnd s fie deschis ntr-un mod
care permite scrierea. De asemenea trebuie s avem grij unde scriem, deoarece atunci cnd
apelm funcia de scriere, aceasta va scrie ncepnd cu poziia curent, indiferent dac
suprascrie alte date sau nu.
fwrite(&pret,sizeof(pret),1,fisier);

Parametrii au aceleai semnificaii ca i la funcia fread( ).


Dac dorim s scriem la sfritul fiierului, atunci va trebui s ne poziionm dup
ultima nregistrare (cum?) i abia apoi s apelm fwrite( ).
Dac dorim s nlocuim o anumit nregistrare (de exemplu nregistrarea a 2-a), va
trebui s ne poziionm pe ea (cu seek( ) ), iar apoi s dm comanda de scriere n fiier:
fseek(fisier, sizeof(pret), SEEK_SET);
fwrite(&pret, sizeof(pret), 1, fisier);

Funcia fseek( ) ne va poziiona la sizeof(pret) octei de nceputul fiierului (care


reprezint de fapt nceputul nregistrrii nr. 2), iar funcia fwrite( ) va scrie acolo variabila
pret, peste ce era scris nainte (se va nlocui vechea nregistrare cu cea nou). Nu se poate
aduga n mod direct o nou nregistrare, care s se adauge ntre 2 deja existente: dac avem
succesiunea 200 500 600 800 i dorim s adugm 300 ntre prima i cea de-a 2-a
nregistrare, prin poziionarea cursorului naintea nregistrrii 2 i apelarea funciei fwrite( ),
rezultatul va fi 200 300 600 800 i nu 200 300 500 600 800.

3
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere

tergerea din fiier


n C++ nu exist o funcie care s tearg efectiv o nregistrare. i totui . cum
tergem dintr-un fiier informaia care nu mai este necesar?
Exist dou tipuri de tergere: tergere fizic i tergere logic.
tergerea fizic implic tergerea efectiv a informaiei din fiier. (dar parc
spusesem c nu este posibil?). Pentru aceasta se face urmtorul artificiu: se va crea un nou
fiier cu un alt nume n care se vor copia toate nregistrrile, mai puin cea care se dorete s
se tearg, dup care fiierul original va fi ters, iar cel nou creat se va redenumi cu numele
celui ters (folosind funcia rename ( ) ).
remove(nume_fisier);
rename( nume_vechi, nume_nou );

Stergerea logic nu implic nici o tergere fizic din fiier. De aceea este mult mai
rapid. Ea implic introducerea unui caracter special n nregistrarea scris (respectiv o nou
variabil sters de tip boolean care s aib valoarea true implicit sau false dac am ters
nregistrarea, pentru cazul n care avem structuri) care s ne semnaleze c nregistrarea
respectiv este tears i va trebui ignorat de acum nainte n toate operaiile din fiier.
Exemplu: avem variabila pret care are valoarea 500. Atunci cnd dorim s o
tergem, i vom modifica doar valoarea n fiier din 500 n -500 (am adugat semnul minus).
Prin convenie, am stabilit c nu exist nici un pre negativ. Prin introducerea semnului
minus, am semnalat c nregistrarea respectiv am ters-o i va trebui ignorat pentru
operaiile ulterioare de citire i scriere, dei ea exist n continuare n fiier.
Atenie:
Dac avem urmtoarea secven de nregistrri n fiier: -200 500 600 900 i dorim
s modificm valoarea nregistrrii 500, n 550, va trebui s ne poziionm n fiier dup
primii sizeof(pre) octei (adic nainte de nregistrarea numrul 2) i nu la nceputul
fiierului, cci chiar dac prima nregistrare este tears logic (-200), ea exist n fiier.

Exemplu de lucru cu fiiere


Vom gestionm structuri de date de forma:
typedef struct{
int numar;
int sold;
}cont;

void main(void)
{
char fisier[]="banca.dat";
int tasta;
do{
printf("\ni-iesire "
"c-creare fisier "
"a-adaugare cont "
"d-depunere "
"l- listare "
);

4
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere
while( !_kbhit() );
tasta=getche();
tasta=tolower(tasta);
printf("\n");
switch(tasta)
{
case 'c':
creare(fisier);
break;
case 'a':
adauga(fisier);
break;
case 'd':
depune(fisier);
break;
case 'l':
listare(fisier);
break;
}
}while(tasta!='i');
}

Utilizatorului i se afieaz o list de opiuni, fiecrei opiuni corespunzndu-i o tast


i i se cere s apese tasta care s-l duc la opiunea dorit.
Prima opiune este creare fiier i de fapt nu ar trebui s fie lsat la ndemna
utilizatorului obinuit deoarece are ca efect distrugerea vechiului fiier, n caz c acesta
exist.
void creare(char* nume)
{
FILE *f;
if((f=fopen(nume,"wb"))!=NULL)
{
fclose(f);
printf("creat cu succes");
}
else
printf("eroare\n");
}

Urmtoarea operaiune pe care o implementm este cea de deschidere cont. Aceasta


are ca efect adugarea unei noi nregistrri n fiier.
void adauga(char* nume)
{
cont c;
FILE *f;
if((f=fopen(nume,"ab"))!=NULL)
{
printf("numar cont:");
scanf("%d",&c.numar);
getchar();
c.sold=0;
fwrite(&c,sizeof(c),1,f);

5
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere
fclose(f);
}
else
printf("eroare\n");
}

n continuare o s ne ocupm de depunere (extragerea se trateaz la fel).


void depune(char* nume)
{
cont c,p;
FILE *f;
if((f=fopen(nume,"r+b"))!=NULL)
{
printf("numar cont:");
scanf("%d",&c.numar);
printf("valoare depunere:");
scanf("%d",&c.sold);
while(fread(&p,sizeof(p),1,f)&&
(p.numar !=c.numar));
if(p.numar==c.numar)
{
fseek(f,-(int)sizeof(p),SEEK_CUR);
p.sold+=c.sold;
fwrite(&p,sizeof(p),1,f);
}
else
printf("cont inexistent\n");
fclose(f);
}
else
printf("fisier eroare\n");
}

Pentru a afia coninutul fiierului folosim urmtoarea funcie:


void listare(char* nume)
{
cont c;
FILE *f;
if((f=fopen(nume,"rb"))!=NULL)
{
while(fread(&c,sizeof(c),1,f))
printf("\ncont:%d sold:%d",c.numar,c.sold);
fclose(f);
}
else
printf("eroare\n");
}

Probleme propuse.
1. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare,
folosind quicksort.
6
PDF created with pdfFactory Pro trial version www.pdffactory.com

Udritoiu tefan
Stoica Spahiu Cosmin

Tehnici de Programare
4. Fiiere

2. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare,
folosind sortarea Shell.
3. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare,
folosind sortarea cu fuziuni (MergeSort).
4. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare,
folosind inseria direct.
5. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare
folosind sortarea prin selecia maximului.
6. S se creeze un fiier care s conin datele dintr-un vector citit de la tastatur, iar
apoi s se sorteze datele scrise n fiier (s se sorteze fiierul), dup un cmp oarecare,
folosind sortarea prin selecia minimului.
7. S se creeze un fiier care s conin date despre studeni. Se folosete structur
Student care s conin nume student, prenume student, not, materie. S se sorteze datele
scrise n fiier dup nume student. S se tearg o anumit nregistrare din fiier.

7
PDF created with pdfFactory Pro trial version www.pdffactory.com

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