Sunteți pe pagina 1din 14

Capitolul VII

FIIERE
7.1. Caracteristicile generale ale fiierelor
7.2. Deschiderea unui fiier
7.3. nchiderea unui fiier
7.4. Prelucrarea fiierelor text
7.4.1. Prelucrarea la nivel de caracter
7.4.2. Prelucrarea la nivel de cuvnt

7.4.3. Prelucrarea la nivel de ir de caractere


7.4.4. Intrri/ieiri formatate
7.5. Intrri/ieiri binare
7.6. Poziionarea ntr-un fiier
7.7. Funcii utilitare pentru lucrul cu fiiere
7.7. Alte operaii cu fiiere

7.1. CARACTERISTICILE GENERALE ALE FIIERELOR


Noiunea de fiier desemneaz o colecie de informaii memorat pe un suport permanent (de obicei discuri
magnetice), perceput ca un ansamblu, creia i se asociaz un nume (n vederea conservrii i regsirii
ulterioare).
Caracteristicile unui fiier (sub sistem de operare MS-DOS) sunt :
Dispozitivul logic de memorare (discul);
Calea (n structura de directoare) unde este memorat fiierul;
Numele i extensia;
Atributele care determin operaiile care pot fi efectuate asupra fiierului (de exemplu: R-read-only citire; W-write-only scriere; RW-read-write citire/scriere; H-hidden - nu se permite nici mcar vizualizarea;
S-system - fiiere sistem asupra crora numai sistemul de operare poate realiza operaii operaii, etc.).
Lucrul cu fiiere n programare ofer urmtoarele avantaje:
Prelucrarea de unei cantiti mari de informaie obinut din diverse surse cum ar fi execuia prealabil a
unui alt program;
Stocarea temporar pe suport permanent a informaiei n timpul execuiei unui program pentru a evita
suprancrcarea memoriei de lucru;
Prelucrarea aceleeai colecii de informaii prin mai multe programe.
n limbajul C, operaiile asupra fiierelor se realizeaz cu ajutorul unor funcii din biblioteca standard
(stdio.h). Transferurile cu dipozitivele periferice (tastatur, monitor, disc, imprimant, etc.) se fac prin
intermediul unor dispozitive logice identice numite stream-uri (fluxuri) i prin intermediul sistemului de
operare. Un flux de date este un fiier sau un dispozitiv fizic tratat printr-un pointer la o structur de tip
FILE (din header-ul stdio.h). Cnd un program este executat, n mod automat, se deschid urmtoarele
fluxuri de date predefinite, dispozitive logice (n stdio.h):
stdin
(standard input device) - dispozitivul standard de intrare (tastatura) - ANSII C;
stdout (standard output device) - dispozitivul standard de ieire (monitorul) - ANSII C;
stderr
(standard error output device) - dispozitivul standard de eroare (de obicei un fiier care
conine mesajele de eroare rezultate din execuia unor funcii) - ANSII C;
stdaux (standard auxiliary device) - dispozitivul standard auxiliar (de obicei interfaa serial auxiliar)
- specifice MS-DOS;
stdprn (standard printer) - dispozitivul de imprimare - specifice MS-DOS.
n abordarea limbajului C (impus de stdio.h), toate elementele care pot comunica informaii cu un program
sunt percepute - n mod unitar - ca fluxuri de date. Datele introduse de la tastatur formeaz un fiier de
intrare (fiierul standard de intrare). Datele afiate pe monitor formeaz un fiier de ieire (fiierul
standard de ieire). Sfritul oricrui fiier este indicat printr-un marcaj de sfrit de fiier (end of file). n
cazul fiierului standard de intrare, sfritul de fiier se genereaz prin Ctrl+Z (^Z) (sub MS-DOS) (sau
Ctrl+D sub Linux). Acest caracter poate fi detectat prin folosirea constantei simbolice EOF (definit n
69

fiierul stdio.h), care are valoarea -1. Aceast valoare nu rmane valabil pentru fiierele binare, care pot
conine pe o poziie oarecare caracterul \x1A.
De obicei, schimbul de informaii dintre programe i periferice se realizeaz folosind zone tampon. O zon
tampon pstreaz una sau mai multe nregistrri. Prin operaia de citire, nregistrarea curent este transferat
de pe suportul extern n zona tampon care i corespunde, programul avnd apoi acces la elementele
nregistrrii din zona tampon. n cazul operaiei de scriere, nregistrarea se construiete n zona tampon, prin
program, fiind apoi transferat pe suportul extern al fiierului. n cazul monitoarelor, nregistrarea se
compune din caracterele unui rnd. De obicei, o zon tampon are lungimea multiplu de 512 octei. Orice
fiier trebuie deschis inainte de a fi prelucrat, iar la terminarea prelucrrii lui, trebuie nchis.
Fluxurile pot fi de tip text sau de tip binar. Fluxurile de tip text mpart fiierele n linii separate prin
caracterul \n (newline=linie nou), putnd fi citite ca orice fiier text. Fluxurile de tip binar transfer
blocuri de octei (fr nici o structur), neputnd fi citite direct, ca fiierele text.
Prelucrarea fiierelor se poate face la dou niveluri:
Nivelul superior de prelucrare a fiierelor n care se utilizeaz funciile specializate n prelucrarea
fiierelor.
Nivelul inferior de prelucrare a fiierelor n care se utilizeaz direct facilitile oferite de sistemul de
operare, deoarece, n final, sarcina manipulrii fiierelor revine sistemului de operare. Pentru a avea
acces la informaiile despre fiierele cu care lucreaz, sistemul de operare folosete cte un descriptor
(bloc de control) pentru fiecare fiier.
Ca urmare, exist dou abordri n privina lucrului cu fiiere:
abordarea implementat n stdio.h, asociaz referinei la un fiier un stream (flux de date), un pointer
ctre o structur FILE.
abordarea definit n header-ul io.h (input/output header) asociaz referinei la un fiier un aa-numit
handle (n cele ce urmeaz acesta va fi tradus prin indicator de fiier) care din punct de vedere al tipului
de date este in;
Scopul lucrului cu fiiere este acela de a prelucra informaia coninut. Pentru a putea accesa un fiier va
trebui s-l asociem cu unul din cele dou modaliti de manipulare. Acest tip de operaie se mai numete
deschidere de fiier. nainte de a citi sau scrie ntr-un fiier (neconectat automat programului), fiierul trebuie
deschis cu ajutorul funciei fopen din biblioteca standard. Funcia primete ca argument numele extern al
fiierului, negociaz cu sistemul de operare i retuneaz un nume (identificator) intern care va fi utilizat
ulterior la prelucrarea fiireului. Acest identificator intern este un pointer la o structur care conine
informaii despre fiier (poziia curent n buffer, dac se citete sau se scrie n fiier, etc.). Utilizatorii nu
trebuie s cunoasc detaliile, singura declaraie necesar fiind cea pentru pointerul de fiier.
Exemplu:
FILE *fp;
Operaiile care pot fi realizate asupra fiierelor sunt:
deschiderea unui fiier;
scrierea ntr-un fiier;
citirea dintr-un fiier;
poziionarea ntr-un fiier;
nchiderea unui fiier.

7.2. DESCHIDEREA UNUI FIIER

Funcia fopen
Creaz un flux de date ntre fiierul specificat prin numele extern ( nume_fiier) i programul C.
Parametrul mod specific sensul fluxului de date i modul de interpretare a acestora. Funcia returneaz
un pointer spre tipul FILE, iar n caz de eroare - pointerul NULL (prototip n stdio.h).
FILE *fopen(const char *nume_fiier, const char *mod);
Parametrul mod este o constant ir de caractere, care poate conine caracterele cu semnificaiile:

70

r : flux de date de intrare; deschidere pentru citire;


w : flux de date de ieire; deschidere pentru scriere (creaz un fiier nou sau suprascrie coninutul
anterior al fiierului existent);
a : flux de date de ieire cu scriere la sfritul fiierului, adugare, sau crearea fiierului n cazul n
care acesta nu exist;
+ : extinde un flux de intrare sau ieire la unul de intrare/ieire; operaii de scriere i citire asupra
unui fiier deschis n condiiile r, w sau a.
b : date binare;
t : date text (modul implicit).
Exemple:
"r+" deschidere pentru modificare (citire i scriere);
"w+" deschidere pentru modificare (citire i scriere);
"rb" citire binar;
"wb" scriere binar;
"r+b" citire/scriere binar.

Funcia freopen (stdio.h)


Asociaz un nou fiier unui flux de date deja existent, nchiznd legtura cu vechiul fiier i ncercnd
s deschid una nou, cu fiierul specificat. Funcia returneaz pointerul ctre fluxul de date specificat,
sau NULL n caz de eec (prototip n stdio.h).
FILE*freopen(const char*nume_fi,const char*mod,FILE *flux_date);

Funcia open
Deschide fiierul specificat conform cu restriciile de acces precizate n apel. Returneaz un ntreg care
este un indicator de fiier sau -1 (n caz de eec) (prototip n io.h).
int open(const char *nume_fiier, int acces [,int mod]);
Restriciile de acces se precizeaz prin aplicarea operatorului | (disjuncie logic la nivel de bit) ntre
anumite constante simbolice, definite n fcntl.h, cum sunt :
O_RDONLY
- citire;
O_WRONLY
- scriere
O_RDWR
- citire i scriere
O_CREAT
- creare
O_APPEND
- adugare la sfritul fiierului
O_TEXT
- interpretare CR-LF
O_BINARY
- nici o interpretare.,
Restriciile de mod de creare se realizeaz cu ajutorul constantelor:
S_IREAD
- permisiune de citire din fiier
S_IWRITE
- permisiune de scriere din fiier, eventual legate prin operatorul |.

Funcia creat
Creaz un fiier nou sau l suprascrie n cazul n care deja exist. Returneaz indicatorul de fiier sau -1
(n caz de eec). Parametrul un_mod este obinut n mod analog celui de la funcia de deschidere
(prototip n io.h).
int creat(const char *nume_fiier, int un_mod);

Funcia creatnew
Creaz un fiier nou, conform modului specificat. Returneaz indicatorul fiierului nou creat sau rezultat
de eroare (-1), dac fiierul deja exist (prototip n io.h).
int creatnew(const char *nume_fiier, int mod);

Dup cum se observ, informaia furnizat pentru deschiderea unui fiier este aceeai n ambele abordri,
diferena constnd n tipul de date al entitaii asociate fiierului. Implementarea din io.h ofer un alt tip de
control la nivelul comunicrii cu echipamentele periferice (furnizat de funcia ioctrl), asupra cruia nu
vom insista, deoarece desfurarea acestui tip de control este mai greoaie, dar mai profund.
71

7.3. NCHIDEREA UNUI FIIER

Funcia fclose
int fclose(FILE *pf);
Funcia nchide un fiier deschis cu fopen i elibereaz memoria alocat (zona tampon i structura
FILE). Returneaz valoarea 0 la nchiderea cu succes a fiierului i -1 n caz de eroare (prototip n
stdio.h).

Funcia fcloseall
int fcloseall(void);
nchide toate fluxururile de date i returneaz numrul fluxurilor de date nchise (prototip n stdio.h).

Funcia close
int close(int indicator);
nchide un indicator de fiier i returneaz 0 (n caz de succes) sau -1 n caz de eroare (prototip n io.h).
7.4. PRELUCRAREA FIIERELOR TEXT

Dup deschiderea unui fiier, toate operaiile asupra fiierului vor fi efectuate cu pointerul su. Operaiile de
citire i scriere ntr-un fiier text pot fi:
intrri/ieiri la nivel de caracter (de octet);
intrri/ieiri la nivel de cuvnt (2 octei);
intrri/ieiri de iruri de caractere;
intrri/ieiri cu formatare.
Comunicarea de informaie de la un fiier ctre un program este asigurat prin funcii de citire care transfer
o cantitate de octei (unitatea de msur n cazul nostru) din fiier ntr-o variabil-program pe care o vom
numi buffer, ea nsi avnd sensul unei niruiri de octei prin declaraia void *buf. Comunicarea de
informaie de la un program ctre un fiier este asigurat prin funcii de scriere care transfer o cantitate de
octei dintr-o variabil-program de tip buffer n fiier.
Fiierele sunt percepute n limbajul C ca fiind, implicit, secveniale (informaia este parcurs succesiv,
element cu element). Pentru aceasta, att fluxurile de date ct i indicatorii de fiier au asociat un indicator
de poziie curent n cadrul fiierului. Acesta este iniializat la 0 n momentul deschiderii, iar operaiile de
citire, respectiv scriere, se refer la succesiunea de octei care ncepe cu poziia curent. Operarea asupra
fiecrui octet din succesiune determin incrementarea indicatorului de poziie curent.
7.4.1. PRELUCRAREA UNUI FIIER LA NIVEL DE CARACTER
Fiierele pot fi scrise i citite caracter cu caracter folosind funciile putc (pentru scriere) i getc (citire).
Funcia putc
int putc (int c, FILE *pf);
c este codul ASCII al caracterului care se scrie n fiier;
pf este pointerul spre tipul FILE a crui valoare a fost returnat de funcia fopen.
Funcia putc returneaz valoarea lui c (valoarea scris n caz de succes), sau 1 ( EOF) n caz de eroare
sau sfrit de fiier.

Funcia getc

int getc (FILE *pf);


Funcia citete un caracter dintr-un fiier (pointerul spre tipul FILE transmis ca argument) i returneaz
caracterul citit sau EOF la sfrit de fiier sau eroare.

72

Exerciiu: S se scrie un program care creaz un fiier text n care se vor scrie caracterele introduse de la
tastatur (citite din fiierul standard de intrare), pn la ntlnirea caracterului ^Z = Ctrl+Z.
#include <stdio.h>
#include <process.h>
void main()
{
int c, i=0; FILE *pfcar;
char mesaj[]="\nIntrodu caractere urmate de Ctrl+Z (Ctrl+D sub Linux):\n";
char eroare[]="\n Eroare deschidere fiier \n";
while(mesaj[i]) putchar(mesaj[i++]);
pfcar=fopen("f_car1.txt","w");
// crearea fiierului cu numele extern f_car1.txt
if(pfcar==NULL)
{
i=0;
while(eroare[i])putc(eroare[i++],stdout);
exit(1);
}while((c=getchar())!=EOF)
// sau: while ((c=getc(stdin)) != EOF)
putc(c,pfcar);
// scrierea caracterului n fiier
fclose(pfcar);
// nchiderea fiierului
}

Exerciiu: S se scrie un program care citete un fiier text, caracter cu caracter, i afieaz coninutul
acestuia.
#include <stdio.h>
#include <process.h>
void main()
{
int c, i=0;
FILE *pfcar;
char eroare[]="\n Eroare deschidere fiier \n";
pfcar=fopen("f_car1.txt","r");
//deschiderea fiierului numit f_car1.txt n citire
if(pfcar==NULL)
{
i=0;
while(eroare[i])putc(eroare[i++],stdout);
exit(1);
} while((c=getc(pfcar))!=EOF)
//citire din fiier, la nivel de caracter
putc(c,stdout);

//scrierea caracterului citit n fiierul standard de ieire (afiare pe monitor)


fclose(pfcar);
}

7.4.2. PRELUCRAREA UNUI FIIER LA NIVEL DE CUVNT


Funciile putw i getw (putword i getword) sunt echivalente cu funciile putc i getc, cu diferena c
unitatea transferat nu este un singur octet (caracter), ci un cuvnt (un int).
int getw(FILE *pf);
int putc (int w, FILE *pf);
Se recomand utilizarea funciei feof pentru a testa ntlnirea sfritului de fiier.
Exemplu:
int tab[100];
FILE *pf;

// . . . deschidere fiier
while (!feof(pf)){
for (int i=0; i<100; i++){
if (feof(pf))
break;

73

tab[i]=getw(pf);

//citire din fiier la nivel de cuvnt i memorare n vectorul tab


// . . .
}
}
printf("Sfarit de fiier\n");

7.4.3. PRELUCRAREA UNUI FIIER LA NIVEL DE IR DE CARACTERE


ntr-un fiier text, liniile sunt considerate ca linii de text separate de sfritul de linie ( '\n'), iar n memorie,
ele devin iruri de caractere terminate de caracterul nul ( '\0'). Citirea unei linii de text dintr-un fiier se
realizeaz cu ajutorul funciei fgets, iar scrierea ntr-un fiier - cu ajutorul funciei fputs.
Funcia fgets este indentic cu funcia gets, cu deosebirea c funcia gets citete din fiierul standard de
intrare (stdin). Funcia fputs este indentic cu funcia puts, cu deosebirea funcia puts scrie n fiierul
standard de ieire (stdout).

Funcia fputs

int fputs(const char *s, FILE *pf);


Funcia scrie un ir de caractere ntr-un fiier i primete ca argumente pointerul spre zona de memorie
(buffer-ul) care conine irul de caractere ( s) i pointerul spre structura FILE. Funcia returneaz ultimul
caracter scris, n caz de succes, sau -1 n caz de eroare.

Funcia fgets

char *fgets(char *s, int dim, FILE *pf);


Funcia citete maximum dim-1 octei (caractere) din fiier, sau pn la ntlnirea sfaritului de linie.
Pointerul spre zona n care se face citirea caracterelor este s. Terminatorul null ('\0') este plasat automat la
sfritul irului (buffer-lui de memorie). Funcia returneaz un pointer ctre buffer-ul n care este memorat
irul de caractere, n caz de succes, sau pointerul NULL n cazul eecului.
Exerciiu: S se scrie un program care creaz un fiier text n care se vor scrie irurile de caractere introduse
de la tastatur.
#include <stdio.h>
void main()
{
int n=250; FILE *pfsir;
char mesaj[]="\nIntrodu siruri car.urmate de Ctrl+Z(Ctrl+D sub Linux):\n";
char sir[250],*psir;
fputs(mesaj,stdout);
pfsir=fopen("f_sir.txt","w"); //deschiderea fiierului f_ir.txt pentru scriere
psir=fgets(sir,n,stdin);
// citirea irurilor din fiierul standard de intrare
while(psir!=NULL)
{
fputs(sir,pfsir);
// scrierea n fiierul text
psir=fgets(sir,n,stdin);
}
fclose(pfsir);
}

Exerciu: S se scrie un program care citete un fiier text, linie cu linie, i afieaz coninutul acestuia
#include <stdio.h>
void main()
{
int n=250; FILE *pfsir; char sir[250],*psir;
pfsir=fopen("f_sir.txt","r"); psir=fgets(sir,n,pfsir);
while(psir!=NULL)
{

74

//sau: puts(sir);
//afiarea (scrierea n fiierul standard de ieire) irului (liniei) citit din fiierul text
psir=fgets(sir,n,pfsir);
//citirea unei linii de text din fiier
fputs(sir,stdout);

}
fclose(pfsir);}

7.4.4. INTRRI/IEIRI FORMATATE


Operaiile de intrare/ieire formatate permit citirea, respectiv scrierea ntr-un fiier text, impunnd un anumit
format. Se utilizeaz funciile fscanf i fprintf, similare funciilor scanf i printf (care permit
citirea/scrierea formatat de la tastatur/monitor).
Funcia fscanf
int fscanf(FILE *pf, const char *format, . . .);
Funcia fprintf
int fprintf(FILE *pf, const char *format, . . .);
Funciile primesc ca parametri fici pointerul ( pf ) spre tipul FILE (cu valoarea atribuit la apelul funciei
fopen), i specificatorul de format (cu structur identic celui prezentat pentru funciile printf i scanf).
Funciile returneaz numrul cmpurilor citite/scrise n fiier, sau -1 ( EOF) n cazul detectrii sfritului
fiierului sau al unei erori.

7.5. INTRRI/IEIRI BINARE


Reamintim c fluxurile de tip binar transfer blocuri de octei (fr nici o structur), neputnd fi citite direct,
ca fiierele text (vezi paragraful 7.1.). Comunicarea de informaie dintre un program i un fiier este
asigurat prin funcii de citire/scriere care transfer un numr de octei, prin intermediul unui buffer.
Funciile de citire
Funcia fread
Citete date dintr-un flux, sub forma a n blocuri (entiti), fiecare bloc avnd dimensiunea dim, ntr-un
buffer (buf). Returneaz numrul de blocuri citite efectiv, sau -1 n caz de eroare (prototip n stdio.h).
size_t fread(void *buf, size_t dim, size_t n, FILE *flux_date);

Funcia read
Citete dintr-un fiier (precizat prin indicatorul su, indicator) un numr de n octei i i memoreaz
n bufferul buf. Funcia returneaz numrul de octei citii efectiv (pentru fiierele deschise n mod text
nu se numr simbolurile de sfirit de linie), sau -1 n caz de eroare (prototip n io.h).
int read(int indicator, void *buf, unsigned n);

Funciile de scriere
Fiierele organizate ca date binare pot fi prelucrate cu ajutorul funciilor fread i fwrite. n acest caz, se
consider c nregistrarea este o colecie de date structurate numite articole. La o citire se transfer ntr-o
zon special, numit zona tampon, un numr de articole care se presupune c au o lungime fix.

Funcia fwrite
Scrie informaia (preluat din buffer, buf este pointerul spre zona tampon care conine articolele citite)
ntr-un flux de date, sub forma a n entiti de dimensiune dim. Returneaz numrul de entiti scrise
efectiv, sau -1 n caz de eroare (prototip n stdio.h).
size_t fwrite(const void *buf, size_t dim, size_t n, FILE *flx_date);

Funcia write
Scrie ntr-un fiier (desemnat prin indicatorul su, indicator) un numr de n octei preluai dintr-un
buffer (buf este pointerul spre acesta). Returneaz numrul de octei scrii efectiv sau -1 n caz de
75

eroare (prototip n io.h).


int write(int indicator, void *buf, unsigned n);
Exerciu: S se scrie un program care creaz un fiier binar n care se vor introduce numere reale, nenule.
#include <iostream.h>
#include <stdio.h>
int main()
{ FILE *f; double nr; int x;
if ((f= fopen("test_nrb.dat", "wb")) == NULL) //deschidere flux binar, scriere
{
cout<<"\nNu se poate deschide fiierul test_nrb.dat"<<'\n';
return 1;
}
cout<<"\nIntroducei numere(diferite de 0) terminate cu un 0:"<<'\n';
cin>>nr;
while(nr!=0)
{
x=fwrite(&nr, sizeof(nr), 1, f);
//scriere n fiier
cin>>nr;
}
fclose(f);
return 0;
}

Exemplu: S se scrie un program ce citete dintr-un fiier binar numere reale, nenule.
#include <iostream.h>
#include <stdio.h>
int main()
{ FILE *f; double buf;
if ((f= fopen("test_nrb.dat", "rb")) == NULL)
{
cout<<"\nNu se poate deschide fiierul test_nrb.dat"<<'\n';
return 1;
}
cout<<"\nNumerele nenule citite din fiier sunt:"<<'\n';
while((fread(&buf, sizeof(buf), 1, f))==1)

// funcia sizeof(buf) care returneaza numarul de octei necesari variabilei buf.


cout<<buf<<"
fclose(f);
cout<<'\n';
return 0;

";

7.6. POZIIONAREA NTR-UN FIIER


Pe lng mecanismul de poziionare implicit (asigurat prin operaiile de citire i scriere) se pot folosi i
operaiile de poziionare explicit.

Funcia fseek
int fseek(FILE *pf, long deplasament, int referina);
Funcia deplaseaz capul de citire/scriere al discului, n vederea prelucrrii nregistrrilor fiierului
ntr-o ordine oarecare. Funcia seteaz poziia curent n fluxul de date la n octei fa de referin):
deplasament definete numrul de octei peste care se va deplasa capul discului;
referina poate avea una din valorile:
0 - nceputul fiierului (SEEK_SET);
1 - poziia curent a capului (SEEK_CUR);
2 - sfritul fiierului (SEEK_END).
Funcia returneaz valoarea zero la poziionarea corect i o valoare diferit de zero n caz de eroare
(prototip n stdio.h).
76

Funcia lseek
int lseek(int indicator, long n, int referinta);
Seteaza poziia curent de citire/scriere n fiier la n octei faa de referin. Returneaz valoarea 0 n
caz de succes i diferit de zero n caz de eroare (prototip n io.h).

Funcia fgetpos
int fgetpos(FILE *flux_date, fpos_t *poziie);
Determin poziia curent (pointer ctre o structur, fpos_t, care descrie aceast poziie n fluxul de
date). nscrie valoarea indicatorului n variabila indicat de poziie. Returneaz 0 la determinarea cu
succes a acestei poziii sau valoare diferit de zero n caz de eec. Structura care descrie poziia poate fi
transmis ca argument funciei fsetpos (prototip n stdio.h).

Funcia fsetpos
int fsetpos(FILE *flux_date, const fpos_t *poziie);
Seteaz poziia curent n fluxul de date (atribuie indicatorului valoarea variabilei indicate poziie),
la o valoare obinut printr apelul funciei fgetpos. Returneaz valoarea 0 n caz de succes, sau diferit
de 0 n caz de eec (prototip n stdio.h).

Exist funcii pentru modificarea valorii indicatorului de poziie i de determinare a poziiei curente a
acestuia.
Funcia ftell
long ftell(FILE *pf);
Indic poziia curent a capului de citire n fiier. Funcia returneaz o valoare de tip long int care
reprezint poziia curent n fluxul de date (deplasamentul n octei a poziiei capului fa de nceputul
fiierului) sau -1L n caz de eroare (prototip n stdio.h).

Funcia tell

long tell(int indicator);


Returneaz poziia curent a capului de citire/scriere n fiier (exprimat n numr de octei fa de
nceputul fiierului), sau -1L n caz de eroare (prototip n io.h).

Funcia rewind
void rewind(FILE *flux_date);
Poziioneaz indicatorul la nceputul fluxului de date specificat ca argument (prototip n stdio.h).

7.7. FUNCII UTILITARE PENTRU LUCRUL CU FIIERE


Funcii de testare a sfritului de fiier
Funcia feof
int feof(FILE *flux_date);
Returneaz o valoare diferit de zero n cazul ntlnirii sfritului de fiier sau 0 n celelalte cazuri
(prototip n stdio.h).

Funcia eof
int eof(int indicator);
Returneaz valoarea 1 dac poziia curent este sfritul de fiier, 0 dac indicatorul este poziionat n
alt parte, sau -1 n caz de eroare (prototip n io.h).

Funcii de golire a fluxurilor de date


Funcia fflush
int fflush(FILE *flux_date);
Golete un fluxul de date specificat ca argument. Returneaz 0 n caz de succes i -1 ( EOF) n caz de
eroare (prototip n stdio.h).

77

Funcia flushall

int flushall(void);
Golete toate fluxurile de date existente, pentru cele de scriere efectund i scrierea n fiiere.
Returneaz numrul de fluxuri asupra crora s-a efectuat operaia (prototip n stdio.h).

7.7. ALTE OPERAII CU FIIERE


Funcii care permit operaii ale sistemului de operare asupra fiierelor
Funcia remove
int remove(const char *nume_fiier);
terge un fiier. Returneaz valoarea 0 pentru operaie reuit i -1 pentru operaie euat (prototip n
stdio.h).

Funcia rename
int rename(const char *nume_vechi, const char *nume_nou);
Redenumete un fiier. Returneaz 0 pentru operaie reuita i -1 n cazul eecului (prototip n stdio.h).

Funcia unlink
int unlink(const char *nume_fiier);
terge un fiier. Returneaz 0 la operaie reuit i -1 la eec; dac fiierul are permisiune read-only,
funcia nu va reui operaia (prototip n io.h, stdio.h).

Funcii care permit manipularea aceluiai fiier prin dou indicatoare de fiier independente
Funcia dup
int dup(int indicator);
Duplic un indicator de fiier. Returneaz noul indicator de fiier pentru operaie reuit sau -1 n cazul
eecului (prototip n io.h).

Funcia dup2
int dup2(int indicator_vechi, int indicator_nou);
Duplic un indicator de fiier la valoarea unui indicator de fiier deja existent. Returneaz 0 n caz de
succes i -1 n caz de eec (prototip n io.h).

Funcii pentru aflarea sau modificarea dimensiunii n octei a fiierelor


Funcia chsize
int chsize(int indicator, long lungime);
Modific dimensiunea unui fiier, conform argumentului lungime. Returneaz 0 pentru operaie reuit
sau -1 n caz de eec (prototip n stdio.h).

Funcia filelength
long filelength(int indicator);
Returneaz lungimea unui fiier (n octei) sau -1 n caz de eroare (prototip n io.h).

Funcii de lucru cu fiiere temporare care ofer faciliti de lucru cu fiiere temporare prin generarea de
nume unice de fiier n zona de lucru.
Funcia tmpfile
FILE *tmpfile(void);
Deschide un fiier temporar, ca flux de date, n mod binar (w+b). Returneaz pointerul ctre fiierul
deschis n cazul operaiei reuite, sau NULL n caz de eec (prototip n stdio.h).

Funcia tmpnam

char *tmpnam(char *sptr);


Creaz un nume unic pentru fiierul temporar (prototip n stdio.h).

78

Funcia creattemp
int creattemp(char *cale, int attrib);
Creaz un fiier unic ca nume, cu atributele specificate n argumentul attrib (prin _fmode,O_TEXT sau
O_BINARY), n directorul dat n argumentul cale. Returneaz indicatorul (handler-ul) ctre fiierul
creat sau -1 (i setarea errno) n cazul eecului (prototip n io.h).

Exemplu: S se creeze un fiier binar, care va conine informaiile despre angajaii unei ntreprinderi: nume,
marca, salariu. S se afieze apoi coninutul fiierului.
#include<iostream.h>
#include <stdio.h>
#include <ctype.h>
typedef struct
{ char nume[20];int marca;double salariu;
}angajat;
union
{angajat a;char sbinar[sizeof(angajat)];}buffer;
int main()
{angajat a; FILE *pf; char cont;char *nume_fis;
cout<<"Nume fisier care va fi creat:"; cin>>nume_fis;
if ((pf= fopen(nume_fis, "wb")) == NULL)
{ cout<<"\nEroare creare fiier "<<nume_fis<<"!\n";
return 1;
}
do
{cout<<"Marca : ";cin>>a.marca;
cout<<"Nume : ";cin>>a.nume;
cout<<"Salariu :";cin>>a.salariu;
buffer.a=a;
fwrite(buffer.sbinar,1,sizeof(angajat),pf);
cout<<"Continuati introducerea de date (d/n) ?";
cin>>cont;
} while(toupper(cont)!='N');
fclose(pf);

//citirea informatiilor
if ((pf= fopen(nume_fis, "rb")) == NULL)
{ cout<<"\nEroare citire fiier "<<nume_fis<<"!\n";
return 1;
}
for(;;)
{
fread(buffer.sbinar,1,sizeof(a),pf);
a=buffer.a1;
if(feof(pf)) exit(1);
cout<<" Marca : "<<a.marca;
cout<<" Numele : "<<a.nume<<'\n';
cout<<" Salariul : "<<a.salariu<<'\n';
}
fclose(pf);
}

Exemplu: Aplicaie pentru gestiunea materialelor dintr-un depozit. Aplicaia va avea un meniu principal i va
permite gestiunea urmtoarelor informaii: codul materialului (va fi chiar "numrul de ordine"), denumirea
acestuia, unitatea de msur, preul unitar, cantitatea contractat i cea recepionat (vectori cu 4 elemente).
Memorarea datelor se va face ntr-un fiier de date (un fiier binar cu structuri), numit "material.dat".
Aplicaia conine urmtoarele funcii:
1. help() - informare privind opiunile programului
2. Funcii pentru fiierele binare, care s suplineasc lipsa funciilor standard pentru organizarea direct a
fiierelor binare:
citireb()
- citire n acces direct din fiier;
79

- scriere n acces direct n fiier;


- citirea de la terminal a informaiilor despre un material;
- afiarea informaiilor despre un material (apelat de list);
- determinarea lungimii fiierului existent;
- creare fiier.
3. Funcii pentru adaugarea, modificarea, tergerea i listarea de materiale.
scrieb()
citmat()
afismat()
lungfisis()
crefis()

#include <process.h>
#include <iostream.h>
#include <stdio.h>
#include <ctype.h>
typedef struct material
{ int codm,stoc,cant_c[4],cant_r[4];
char den_mat[20],unit_mas[4];
float pre;
};
material mat;
FILE *pf;
void crefis(),adaug(),modif(),sterg(),list(),help();
void main()
{
char opiune;
do
//afiarea unui meniu de opiuni i selecia opiunii
{
cout<<'\n'<<"Opiunea Dvs. de lucru este"<<'\n'
<<"(c|a|m|s|l|e|h pentru help) : ";
cin>>opiune;
switch(opiune)
{
case 'c':case 'C':crefis();break;
case 'a':case 'A':adaug();break;
case 'm':case 'M':modif();break;
case 's':case 'S':terg();break;
case 'l':case 'L':list();break;
case 'h':case 'H':help();break;
case 'e':case 'E':
break;
default:help();
break;
}
}while(toupper(opiune)!='E');
}
void help()
// afiare informaii despre utilizarea meniului i opiunile acestuia
{cout<<"Opiunile de lucru sunt :"<<'\n';
cout<<"
C,c-creare fisier"<<'\n';
cout<<"
A,a-adaugare"<<'\n';
cout<<"
M,m-modificare"<<'\n';
cout<<"
L,l-listare"<<'\n';
cout<<"
S,s-tergere"<<'\n';
cout<<"
H,h-help"<<'\n';
cout<<"
E,e-exit"<<'\n';
}
long int lungfis(FILE *f)
// returneaz lungimea fiierului
{long int posi,posf;
posi=ftell(f); fseek(f,0,SEEK_END);
posf=ftell(f); fseek(f,posi,SEEK_SET);
return posf;
}
void scrieb(int nr,void *a,FILE *f) //scriere n fiierul binar
{long depl=(nr-1)*sizeof(material);
fseek(f,depl,SEEK_SET);
if(fwrite(a,sizeof(material),1,f)!=1)
{cout<<"Eroare de scriere in fiier !"<<'\n';
80

exit(1); }
}
void citireb(int nr,void *a,FILE *f)
//citire din fiierul binar
{long depl=(nr-1)*sizeof(material);
fseek(f,depl,SEEK_SET);
if(fread(a,sizeof(material),1,f)!=1)
{cout<<"Eroare de citire din fiier !"<<'\n';
exit(2);
}
}
void afismat(material *a)
//afiarea informaiilor despre un anumit material
{
int i;
if(a->codm)
{cout<<"Cod material
: "<<a->codm<<'\n';
cout<<"Denumire material: "<<a->den_mat<<'\n';
cout<<"Cantitai contractate:"<<'\n';
for(i=0;i<4;i++)
cout<<"Contractat "<<i<<"
: "<<a->cant_c[i]<<'\n';
cout<<"Cantitai recepionate:"<<'\n';
for(i=0;i<4;i++)
cout<<"Receptionat "<<i<<" : "<<a->cant_r[i]<<'\n';
cout<<"Stoc
: "<<a->stoc<<'\n';
cout<<"Unitate de masura: "<<a->unit_mas<<'\n';
cout<<"Pre unitar
: "<<a->pre<<'\n';
}
else
cout<<"Acest articol a fost ters !"<<'\n';
}
void citmat(material *a)
//citirea informaiilor despre un anumit material
{
int i;float temp;
cout<<"Introduceti codul materialului (0=End): ";cin>>a->codm;
if(a->codm==0) return;
cout<<"Introducei denumirea materialului : ";cin>>a->den_mat;
cout<<"Introducei unitatea de msur : ";cin>>a->unit_mas;
cout<<"Introducei preul : ";cin>>temp;a->pre=temp;
cout<<"Introducei cantitaile contractate : "<<'\n';
for(i=0;i<4;i++)
{cout<<"Contractat "<<i+1<<" : ";cin>>a->cant_c[i]; }
cout<<"Introducei cantitaile recepionate : "<<'\n';
for(i=0;i<4;i++)
{cout<<"Receptionat "<<i+1<<" : ";cin>>a->cant_r[i]; }
}
void crefis()
//deschidere fisier
{
if((pf=fopen("material.dat","r"))!=NULL)
cout<<"Fiierul exista deja !"<<'\n';
else
pf=fopen("material.dat","w");
fclose(pf);
}
void adaug()
//adugare de noi materiale
{
int na; pf=fopen("material.dat","a");//deschidere pentru append
na=lungfis(pf)/sizeof(material);
do
{citmat(&mat);
if(mat.codm) scrieb(++na,&mat,pf);
} while(mat.codm);
fclose(pf);
}

81

void modif()
//modificarea informaiilor despre un material existent
{
int na; char ch; pf=fopen("material.dat","r+");
do
{cout<<"Numarul articolului de modificat este (0=END): ";cin>>na;
if(na)
{citireb(na,&mat,pf);
afismat(&mat);
cout<<"Modificai articol (D/N) ? :";
do
{
cin>>ch;
ch=toupper(ch);
} while(ch!='D' && ch!='N');
if(ch=='D')
{citmat(&mat);
scrieb(na,&mat,pf);
}
}
}while(na);
fclose(pf);
}
void sterg()
//tergerea din fiier a unui material
{ int n;long int na; pf=fopen("material.dat","r+");
mat.codm=0; na=lungfis(pf)/sizeof(material);
do
{
do
{cout<<"Numarul articolului de ters este (0=END): ";cin>>n;
if(n<0||n>na) cout<<"Articol eronat"<<'\n';
}while(!(n>=0 && n<=na));
if(n) scrieb(n,&mat,pf);
}while(n);
fclose(pf);
}
void list()
//afiare informaii despre un anumit material
{
int na; pf=fopen("material.dat","r");
do
{cout<<"Numarul articolului de listat este (0=END): ";cin>>na;
if(na)
{citireb(na,&mat,pf);
afismat(&mat);
cout<<'\n';
}
}while(na);
fclose(pf);
}

82