Sunteți pe pagina 1din 14

9.

Fiiere de date



9.1 Elemente generale


Indiferent de limbajul de programare folosit, operaiile necesare pentru
prelucrarea fiierelor snt:
descrierea fiierului (crearea tabelei care memoreaz caracteristicile fiierului);
asignarea fiierului intern (numele logic) la unul extern (fizic);
deschiderea fiierului;
operaii de acces la date (articole);
nchiderea fiierului.
Pentru lucrul cu fiiere trebuie identificate tipurile acestora, metodele de
organizare, modurile de acces i tipurile de articole acceptate. Din punct de vedere
al tipurilor de date, n C exist un singur tip de fiiere (D): flux de octei (niruire
de octei, fr nici un fel de organizare sau semnificaie). Organizarea acestui flux
de octei este secvenial (A). Accesul la fiiere se poate face secvenial sau direct
(cu excepia fiierelor standard, la care accesul este numai secvenial). n
bibliotecile limbajului exist funcii predefinite pentru prelucrarea fiierelor.
Funciile de prelucrare la nivel superior a fiierelor trateaz fluxul de octei
acordndu-i o semnificaie oarecare. Putem spune c, din punctul de vedere al
prelucrrii, la acest nivel ne putem referi la fiiere text i fiiere binare (A).
Exist fiiere standard, care snt gestionate automat de sistem, dar asupra
crora se poate interveni i n mod explicit (A). Acestea snt:
fiierul standard de intrare (stdin);
fiierul standard de ieire (stdout);
fiierul standard pentru scrierea mesajelor de eroare (stderr);
fiierul standard asociat portului serial (stdaux);
fiierul standard asociat imprimantei cuplate la portul paralel (stdprn).
Fiierele standard pot fi redirectate conform conveniilor sistemului de
operare, cu excepia lui stderr care va fi asociat ntotdeauna monitorului.
tiina nvrii unui limbaj de programare. Teorie

n lucrul cu fiiere (sau la orice apel de sistem), n caz de eroare n timpul
unei operaii se seteaz variabila errno, definit n errno.h, stddef.h i stdlib.h.
Valorile posibile snt definite n stdlib.h.



9.2 Operaii de prelucrare a fiierelor


n limbajul C exist dou niveluri de abordare a lucrului cu fiiere: nivelul
inferior de prelucrare (fr gestiunea automat a zonelor tampon de intrare/ieire)
i nivelul superior de prelucrare (se folosesc funcii specializate de gestiune a
fiierelor). n continuare, prin specificator de fiier se va nelege un nume extern
de fiier, conform conveniilor sistemului de operare. Specificatorul de fiier poate
s conin strict numele fiierului sau poate conine i calea complet pn la el.


9.2.1 Nivelul inferior de prelucrare a fiierelor

Nivelul inferior de prelucrare este folosit rar, numai n programele de
sistem.
La acest nivel, descrierea fiierelor se realizeaz n corpul programelor,
caracteristicile acestora obinndu-se din context. Maniera de prelucrare este
asemntoare celei de la nivelul sistemului de operare. Nu exist un tip anume de
dat, fiierul fiind referit printr-un index care indic intrarea ntr-o tabel de
gestiune a resurselor sistemului de operare. Acest index este de tip int i se numete
manipulator de fiier (handle). Manipulatorul este creat i gestionat de ctre
sistemul de operare. Utilizatorul l folosete pentru a indica sistemului fiierul
asupra cruia dorete s fac prelucrri.
Pentru utilizarea acestui nivel, n programul C trebuie incluse bibliotecile
standard io.h, stat.h i fcntl.h.

Crearea i asignarea unui fiier nou se realizeaz prin apelul funciei
creat, care are urmtorul prototip:

int creat(const char* numef, int protecie);

Funcia returneaz manipulatorul fiierului nou creat; numef este un pointer spre un
ir de caractere care definete specificatorul de fiier, iar protecie definete modul
de protecie a fiierului creat (protecia este dependent de sistemul de operare). n
biblioteca stat.h snt definite urmtoarele valori pentru parametrul protecie:
S_IREAD (citire), S_IWRITE (scriere), S_IEXEC (execuie). Aceste valori pot fi
combinate folosind operatorul | (sau logic pe bii). Funcia creat poate fi apelat i
pentru un fiier existent, efectul fiind acelai cu apelul procedurii rewrite
Fiiere de date

din Pascal (se terge fiierul existent i se creeaz unul gol, cu acelai nume;
coninutul fiierului existent se pierde). n caz de eroare se returneaz valoarea 1
i se seteaz variabila global errno, care definete tipul erorii. Valorile obinuite
pentru errno snt EBADF (manipulator eronat, nu a fost gsit fiierul) sau
EACCES (fiierul nu poate fi accesat).

Deschiderea unui fiier existent se realizeaz prin apelul funciei open,
care are urmtorul prototip:

int open(const char *path,int access[,unsigned mod]);

Funcia returneaz manipulatorul fiierului; numef este pointer spre un ir de
caractere care definete specificatorul de fiier; acces este modul de acces la fiier;
constantele care descriu modurile de acces la fiier snt descrise n fcntl.h. Cele mai
importante snt: O_RDONLY fiierul va fi accesat numai pentru citire;
O_WRONLY fiierul va fi accesat numai pentru scriere; O_RDWR fiierul va
fi accesat att pentru citire ct i pentru scriere; O_CREAT: fiierul va fi creat ca
nou. Aceste moduri pot fi combinate folosind operatorul |. Mod este folosit numai
dac parametrul acces conine i valoarea O_CREAT, caz n care indic modul de
protecie a acestuia: S_IWRITE se permite scrierea n fiier; S_IREAD se
permite citirea din fiier; S_IREAD|S_IWRITE se permite att scrierea, ct i
citirea din fiier.

Citirea dintr-un fiier se realizeaz prin apelul funciei read, care are
urmtorul antet:

int read(int nf, void* zonat, unsigned n);

Funcia returneaz numrul de octei citii din fiier; nf este manipulatorul de fiier
(alocat la crearea sau deschiderea fiierului), zonat este un pointer spre zona
tampon n care se face citirea (aceasta este definit de programator), iar n este
dimensiunea zonei receptoare (numrul maxim de octei care se citesc). Numrul
maxim de octei care pot fi citii este 65534 (deoarece 65535 0xFFF se
reprezint intern la fel ca -1, indicatorul de eroare). n cazul citirii sfritului de
fiier se va returna valoarea 0 (0 octei citii), iar la eroare se returneaz -1 (tipul
erorii depinde de sistemul de operare). Fiierul standard de intrare (stdin) are
descriptorul de fiier 0.

Scrierea ntr-un fiier se realizeaz prin apelul funciei write, care are
urmtorul prototip:

int write(int nf, void* zonat, unsigned n);

Funcia returneaz numrul de octei scrii n fiier; nf este manipulatorul de fiier
(alocat la crearea sau deschiderea fiierului), zonat este un pointer spre zona
tampon din care se face scrierea (aceasta este definit de programator); n este
numrul de octei care se scriu. Numrul maxim de octei care pot fi citii
tiina nvrii unui limbaj de programare. Teorie

este 65534 (deoarece 65535 0xFFF se reprezint intern la fel ca -1, indicatorul
de eroare). n general, trebuie ca la revenirea din funcia write, valoarea returnat
s fie egal cu n; dac este mai mic, s-a produs o eroare (probabil discul este plin).
La scrierea n fiiere text, dac n fluxul octeilor care se scriu apare caracterul LF,
write va scrie n fiier perechea CR/LF. n caz de eroare, valoarea returnat este -1
i se seteaz variabila errno. Fiierul standard de ieire (stdout) are manipulatorul
1, iar cel de eroare (stderr) are manipulatorul 2.

nchiderea unui fiier se realizeaz prin apelul funciei close, care are
urmtorul prototip:

int close(int nf);

Funcia returneaz valoarea 0 (nchidere cu succes) sau -1 (eroare); nf este
manipulatorul de fiier. De asemenea, nchiderea unui fiier se realizeaz automat,
dac programul se termin prin apelul funciei exit.

Poziionarea ntr-un fiier se realizeaz prin apelul funciei lseek, care are
urmtorul prototip:

long lseek(int nf, long offset, int start);

Funcia returneaz poziia fa de nceputul fiierului, n numr de octei; nf este
manipulatorul de fiier; offset este un parametru de tip long (numrul de octei
peste care se va deplasa pointerul n fiier), iar start este poziia fa de care se face
deplasarea: 0 (nceputul fiierului), 1 (poziia curent n fiier) sau 2 (sfritul
fiierului). La eroare returneaz valoarea -1L.

Exemple:
1. Apelul vb=lseek(nf, 0l, 2); realizeaz poziionarea la sfritul fiierului
(n continuare se poate scrie n fiier folosind write);
2. Apelul vb=lseek(nf, 0l, 0); realizeaz poziionarea la nceputul
fiierului.

tergerea unui fiier existent se realizeaz prin apelul funciei unlink, care
are urmtorul prototip:

int unlink(const char* numef);

Funcia returneaz 0 (tergere cu succes) sau -1 (eroare); numef este un pointer spre
un ir de caractere care definete specificatorul de fiier. n caz de eroare se seteaz
variabila errno cu valoarea ENOENT (fiierul nu a fost gsit) sau EACCES
(accesul interzis pentru aceast operaie, de exemplu pentru fiiere read only).
Pentru a putea terge un fiier read only trebuie nti schimbate drepturile de acces
la fiier, folosind funcia chmod:

int chmod(const char *cale, int mod);
Fiiere de date

unde cale este specificatorul de fiier, iar mod noile permisiuni. Permisiunile snt
aceleai ca la funcia open. Rezultatul ntors de chmod are aceeai semnificaie ca
i unlink.

Verificarea atingerii sfritului de fiier se face folosind funcia eof:

int eof(int nf);

unde nf este manipulatorul fiierului. Funcia returneaz valoarea 1 dac pointerul
este poziionat pe sfritul fiierului, 0 n caz contrat i -1 n caz de eroare (nu este
gsit fiierul errno primete valoarea EBADF).

Exemplu:
#include <sys\stat.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <io.h>

int main(void)
{ int handle;
char msg[] = "This is a test";
char ch;
/* create a file */
handle = open("TEST.$$$", O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
/* write some data to the file */
write(handle, msg, strlen(msg));
/* seek to the begining of the file */
lseek(handle, 0L, SEEK_SET);
/* reads chars from the file until we hit EOF */
do {read(handle, &ch, 1);
printf("%c", ch);}
while (!eof(handle));
close(handle);
return 0;}

Bibliotecile limbajului conin i alte funcii pentru prelucrarea fiierelor la
nivel inferior, inclusiv variante ale funciilor anterioare, aprute o dat cu
dezvoltarea sistemelor de operare.


9.2.2 Nivelul superior de prelucrare a fiierelor

La acest nivel, un fiier se descrie ca pointer ctre o structur predefinit
(FILE tabela de descriere a fiierului (FIB)):

FILE* f;

Tipul FILE (descris n stdio.h) depinde de sistemul de operare.
tiina nvrii unui limbaj de programare. Teorie

Fiierul este considerat ca flux de octei, din care funciile de prelucrare
preiau secvene pe care le trateaz ntr-un anumit fel (sau n care insereaz secvene
de octei).
Funciile folosite la acest nivel pot fi mprite n trei categorii: funcii de
prelucrare generale, funcii de citire/scriere cu conversie i funcii de citire/scriere
fr conversie. Funciile de prelucrare general se aplic tuturor fiierelor,
indiferent de tipul informaiei coninute; prelucrarea efectuat de acestea nu are
nici un efect asupra coninutului fiierului. Funciile care lucreaz cu conversie se
aplic fiierelor care conin informaie de tip text (linii de text, separate prin
perechea CR/LF, iar la sfrit se gsete caracterul CTRL-Z). Funciile care
lucreaz fr conversie se aplic fiierelor care conin informaie binar.
Funciile de citire/scriere deplaseaz pointerul de citire/scriere al fiierului,
spre sfritul acestuia, cu un numr de octei egal cu numrul de octei transferai
(fr a trece de sfritul de fiier).

Funcii de prelucrare general
Deschiderea i asignarea se realizeaz prin apelul funciei fopen. Funcia
returneaz un pointer spre o structur de tip FILE (n care snt nscrise date
referitoare la fiierul deschis) sau NULL dac fiierul nu se poate deschide:

FILE* fopen(const char* nume_extern,const char* mod);

Parametrul nume_extern constituie specificatorul de fiier iar mod este un ir de
caractere care specific modul de deschidere a fiierului. Asignarea se realizeaz
prin expresie de atribuire de tipul:

nume_intern=fopen(sir_nume_extern,sir_mod);

Exemplu: FILE* f;
f = fopen("PROD.DAT","r");

Modurile n care poate fi deschis un fiier snt prezentate n tabelul 9.1.

Tabelul 9.1 Modurile de deschidere a unui fiier
Mod Scop
a
Deschide un fiier existent pentru adugare la sfrit (extindere) sau l creeaz
dac nu exist. Este permis numai scrierea. Numai pentru fiiere text.
r Deschide un fiier existent numai pentru citire
w
Suprascrie un fiier existent sau creeaz unul nou, permindu-se numai
operaia de scriere
a+
Deschide un fiier existent pentru adugare la sfrit (extindere) sau l creeaz
dac nu exist. Snt permise citiri i scrieri. Numai pentru fiiere text.
r+ Deschide un fiier existent pentru citire i scriere
w+
Suprascrie un fiier existent sau creeaz unul nou, permindu-se att citiri, ct
i scrieri
Fiiere de date

La opiunile de mai sus se poate aduga b pentru fiiere binare sau t pentru
fiiere text. Dac nu este prezent nici litera b nici litera t, modul considerat
depinde de valoarea variabilei _fmode: dac valoarea este O_BINARY, se
consider fiier binar; dac valoarea este O_TEXT, se consider fiier text.
De obicei implicit este valoarea O_TEXT.

Modurile uzuale pentru deschiderea fiierelor snt prezentate n tabelul 9.2.

Tabelul 9.2 Moduri uzuale pentru deschiderea fiierelor
Operaia de gestiune Fiiere text Fiiere binare
Creare w wb
Consultare r rb
Actualizare nu r+b
Creare i actualizare w+ rwb, w+b
Extindere a nu

nchiderea fiierelor se realizeaz prin apelul funciei fclose, care are
urmtorul prototip:

int fclose(FILE* f);

Funcia nchide fiierul primit ca parametru i returneaz valoarea 0, n caz de
succes, sau -1, n caz de eroare. nainte de nchiderea fiierului, snt golite toate
bufferele asociate lui. Bufferele alocate automat de sistem snt eliberate.

Revenirea la nceputul fiierului se realizeaz prin funcia rewind, cu
prototipul:
void rewind(FILE *f);

Executarea funciei are ca efect poziionarea la nceputul fiierului f (care era
deschis anterior), resetarea indicatorului de sfrit de fiier i a indicatorilor de
eroare (se nscrie valoarea 0). Dup apelul lui rewind poate urma o operaie de
scriere sau citire din fiier.

Testarea sfritului de fiier se realizeaz prin apelul macrodefiniiei feof:

int feof(FILE* f);

Macro-ul furnizeaz valoarea indicatorului de sfrit de fiier asociat lui f. Valoarea
acestui indicator este setat la fiecare operaie de citire din fiierul respectiv (D).
Valoarea ntoars este 0 (fals) dac indicatorul are valoarea sfrit de fiier i diferit
de zero (adevrat) n caz contrar. Apelul lui feof trebuie s fie precedat de apelul
unei funcii de citire din fiier. Dup atingerea sfritului de fiier, toate ncercrile
de citire vor eua, pn la apelul funciei rewind sau nchiderea i redeschiderea
fiierului.
tiina nvrii unui limbaj de programare. Teorie

Golirea explicit a zonei tampon a unui fiier se realizeaz prin apelul
funciei fflush, care are urmtorul prototip:

int fflush(FILE* f);

Dac fiierul f are asociat un buffer de ieire, funcia scrie n fiier toate
informaiile din acesta, la poziia curent. Dac fiierul are asociat un buffer de
intrare, funcia l golete. n caz de succes returneaz valoarea zero, iar n caz de
eroare valoarea EOF (definit n stdio.h).

Exemplu: nainte de a citi un ir de caractere de la tastatur, bufferul trebuie golit
pentru a preveni citirea unui ir vid (datorit unei perechi CR/LF rmase n buffer
de la o citire anterioar a unei valori numerice). tergerea se realizeaz prin apelul:

fflush(stdin);

Aflarea poziiei curente n fiier se realizeaz prin apelul uneia din funciile
fgetpos sau ftell:

int fgetpos(FILE* f,fpos_t* poziie);

Dup apel, la adresa poziie se afl poziia pointerului de citire/scriere din fiierul f,
ca numr relativ al octetului curent. Primul octet are numrul 0. Valoarea returnat
poate fi folosit pentru poziionare cu funcia fsetpos. n caz de succes funcia
ntoarce valoarea 0, iar n caz de eroare, o valoare nenul i seteaz variabila errno
la valoarea EBADF sau EINVAL.

long ftell(FILE* f);

returneaz poziia n fiierul f a pointerului de citire/scriere n caz de succes sau -1L
n caz contrar. Dac fiierul este binar, poziia este dat n numr de octei fa de
nceputul fiierului. Valoarea poate fi folosit pentru poziionare cu funcia fseek.

Modificarea poziiei pointerului de citire/scriere se poate face prin
poziionare relativ:

int fseek(FILE* f,long deplasare,int origine);

unde deplasare reprezint numrul de octei cu care se deplaseaz pointerul n
fiierul f, iar origine reprezint poziia fa de care se deplaseaz pointerul.
Parametrul origine poate fi: SEEK_SET (0) poziionare fa de nceputul
fiierului; SEEK_CUR (1) poziionare fa de poziia curent; SEEK_END (2)
poziionare fa de sfritul fiierului. Funcia returneaz valoarea 0 n caz de
succes (i uneori i n caz de eec). Se semnaleaz eroare prin returnarea unei
valori nenule numai n cazul n care f nu este deschis.
Fiiere de date

Poziionarea absolut se face cu funcia:

int fsetpos(FILE* f,const fpos_t poziie);

Pointerul de citire/scriere se mut n fiierul f la octetul cu numrul indicat de
parametrul poziie (care poate fi o valoare obinut prin apelul lui fgetpos).
Ambele funcii reseteaz indicatorul de sfrit de fiier i anuleaz efectele
unor eventuale apeluri anterioare ale lui ungetc asupra acelui fiier.

Redenumirea sau mutarea unui fiier existent se poate realiza prin apelul
funciei rename, care are urmtorul prototip:

int rename(const char* n_vechi,const char* n_nou);

unde n_vechi reprezint vechiul nume al fiierului, iar n_nou reprezint numele nou.
Dac numele vechi conine numele discului (de exemplu C:), numele nou trebuie
s conin acelai nume de disc. Dac numele vechi conine o cale, numele nou nu
este obligat s conin aceeai cale. Folosind o alt cale se obine mutarea fiierului
pe disc. Folosind aceeai cale (sau nefolosind calea) se obine redenumirea
fiierului. Nu snt permise wildcard-uri (?, *) n cele dou nume.
n caz de succes se ntoarce valoarea 0. n caz de eroare se ntoarce -1 i
errno primete una din valorile: ENOENT nu exist fiierul, EACCES nu
exist permisiunea pentru operaie sau ENOTSAM dispozitiv diferit (mutarea se
poate face doar pe acelai dispozitiv).

tergerea unui fiier existent se poate realiza prin apelul funciei unlink,
prezentat anterior, sau remove, care are urmtorul prototip:

int remove(const char* cale);

unde cale reprezint specificatorul fiierului (trebuie s fie nchis).

Funcii de citire/scriere fr conversie
Funciile efectueaz transferuri de secvene de octei ntre memoria intern
i un fiier de pe disc, fr a interveni asupra coninutului sau ordinii octeilor
respectivi.

Citirea dintr-un fiier binar se realizeaz prin apelul funciei fread, care are
urmtorul prototip:

size_t fread(void* ptr,size_t dim,size_t n,FILE* f);

Funcia citete din fiierul f, de la poziia curent, un numr de n entiti, fiecare de
dimensiune dim, i le depune, n ordinea citirii, la adresa ptr. fread returneaz
numrul de entiti citite. n total se citesc, n caz de succes, n*dim octei. n caz de
eroare sau cnd se ntlnete sfritul de fiier, funcia returneaz o valoare negativ
tiina nvrii unui limbaj de programare. Teorie

sau 0; size_t este definit n mai multe header-e (ntre care stdio.h) i este un tip de
dat folosit pentru a exprima dimensiunea obiectelor din memorie. Este compatibil
cu tipul unsigned.

Exemplu:
struct complex {int x,y} articol;
FILE * f_complex;
if(f_complex=fopen("NR_COMPL.DAT", "rb")
fread(&articol,sizeof(articol),1,f_complex);
else printf("Fisierul nu poate fi deschis");

n exemplul anterior se deschide un fiier binar din care se citete un articol de tip
struct complex care se depune n variabila articol.

Scrierea ntr-un fiier binar se poate realiza prin apelul funciei fwrite, care
are urmtorul prototip:

size_t fwrite(const void* ptr,size_t dim,size_t n,FILE* f);

Funcia scrie n fiierul f, ncepnd cu poziia curent, un numr de n entiti
contigue, fiecare de dimensiune dim, aflate n memorie la adresa ptr; fwrite
returneaz numrul entitilor scrise cu succes. n caz de eroare se returneaz o
valoare negativ.

Exemplu:
struct complex {int x,y} articol;
FILE *pf;
pf=fopen("NR_COMPL.DAT","wb");
fwrite(& articol,sizeof (articol),1,pf);

Exemplul anterior creeaz un fiier binar nou n care scrie o secven de octei
coninnd reprezentarea binar a unei date de tip struct complex.

Exemplu:
S se scrie funcia care calculeaz numrul de articole dintr-un fiier binar,
cunoscnd lungimea n octei a unui articol. Funcia are ca parametri fiierul i
lungimea n octei a unui articol. Prin numele funciei se ntoarce numrul de
articole din fiier.

int nrart(FILE *f, int l)
{long p;
int n;
p=ftell(f);
fseek(f,0,2);
n=ftell(f)/l;
fseek(f,0,p);
return n;}

Fiiere de date

Funcii de citire/scriere cu conversie
Funciile efectueaz transferuri de secvene de octei ntre memoria intern
i un fiier de pe disc, convertind secvena de la reprezentarea intern (binar) la
reprezentarea extern (ASCII) i invers.

Transferul de caractere se efectueaz prin urmtoarele funcii:

int fgetc(FILE* f);
int fputc(int c, FILE *f);
int getc(FILE* f);
int putc(int c, FILE *stream);

Funcia fgetc i macrodefiniia getc returneaz urmtorul caracter din
fiierul f (dup ce l convertete la reprezentarea de tip ntreg fr semn). Dac s-a
ajuns la sfritul fiierului, funcia va ntoarce EOF (valoarea -1). Tot EOF va
ntoarce i dac snt probleme la citirea din fiier.
Funcia fputc i macrodefiniia putc scriu caracterul c n fiierul f. n caz de
eroare se returneaz valoarea c, altfel se returneaz EOF.
Funcia ungetc pune caracterul c n bufferul de citire asociat fiierului f. La
urmtoarea citire cu fread sau getc acesta va fi primul octet/caracter citit. Un al
doilea apel al funciei ungetc, fr s fie citit primul caracter pus n flux, l va
nlocui pe acesta. Apelarea funciilor fflush, fseek, fsetpos sau rewind terge aceste
caractere din flux. n caz de succes, ungetc returneaz caracterul c, iar n caz de
eroare returneaz EOF.

Transferul de iruri de caractere se efectueaz prin funciile:

char* fgets(char* s,int n,FILE* f);
int fputs(const char* s,FILE* f);

Funcia fgets citete un ir de caractere din fiierul f i l depune la adresa s.
Transferul se ncheie atunci cnd s-au citit n-1 caractere sau s-a ntlnit caracterul
newline. La terminarea transferului, se adaug la sfritul irului din memorie
caracterul nul \0. Dac citirea s-a terminat prin ntlnirea caracterului newline,
acesta va fi transferat n memorie, caracterul nul fiind adugat dup el (spre
deosebire de gets, care nu l reine). La ntlnirea sritului de fiier (fr a fi
transferat vreun caracter) sau n caz de eroare fgets returneaz NULL. n caz de
succes returneaz adresa irului citit (aceeai cu cea primit n parametrul s).
Funcia fputs scrie n fiierul f caracterele irului aflat la adresa s.
Terminatorul de ir (\0) nu este scris i nici nu se adaug caracterul newline (spre
deosebire de puts). n caz de succes fputs returneaz ultimul caracter scris. n caz
de eroare returneaz EOF.

Transferul de date cu format controlat este realizat prin funciile:
int fprintf(FILE* f,const char* format[,]);
int fscanf(FILR* f,const char* format[,]);
tiina nvrii unui limbaj de programare. Teorie

Cele dou funcii lucreaz identic cu printf i scanf. Singura diferen
const n fiierul n/din care se transfer datele. Dac printf i scanf lucreaz cu
fiierele standard stdin i stdoud, pentru fprintf i fscanf este necesar precizarea
explicit a fiierului cu care se lucreaz, prin parametrul f.
Dei nu lucreaz cu fiiere n mod direct, se pot folosi i funciile

int sprintf(char *s,const char *format[,...]);
int sscanf(const char *s,const char *format[,...]);

Aceste funcii lucreaz identic cu printf i scanf, diferena constnd n entitatea
din/n care se transfer datele. n locul fiierelor standard, acest funcii folosesc o
zon de memorie de tip ir de caractere, a crei adres este furnizat n parametrul
s. irul de la adresa s poate fi obinut prin transfer fr format dintr-un fiier text
(pentru sscanf) sau poate urma s fie scris ntr-un fiier text prin funcia fputs.

Pentru tratarea erorilor se folosesc urmtoarele funcii:

void clearerr (FILE* f);
Funcia reseteaz indicatorii de eroare i indicatorul de sfrit de fiier pentru
fiierul f (se nscrie valoarea 0). O dat ce indicatorii de eroare au fost setai la o
valoare diferit de 0, operaiile de intrare/ieire vor semnala eroare pn la apelul
lui clearerr sau rewind.

int ferror (FILE* nume_intern);

Este o macrodefiniie care returneaz codul de eroare al ultimei operaii de
intrare/ieire asupra fiierului nume_intern (0 dac nu s-a produs eroare).

Exemplu:
#include <stdio.h>
int main(void)
{ FILE *f;
/* deschide fisierul pentru scriere*/
f=fopen("test.ttt","w");
/* se produce eroarela incercarea de citire */
getc(f);
if(ferror(f)) /* s-a produs eroare de I/E? */
{/* afiseaza mesaj de eroare */
printf("Eroare al citirea din test.ttt\n");
//reseteazaindicatorii de eroare si sfirsit de fisier
clearerr(f);}
fclose(f);
return 0;}

Exemplu:
S se scrie un program care calculeaz i afieaz valoarea unei funcii
introduse de la tastatur ntr-un punct dat. Funcia se introduce ca ir de caractere i
poate conine apeluri de funcii standard C (vezi i [Smeu95]).
Fiiere de date

Programul creeaz un fiier surs C (n care este scris forma funciei, ca
subprogram C), apoi compileaz i execut un alt program, care va include
subprogramul creat. Descrierea funciei introduse de la tastatur trebuie s conin
maxim 200 de caractere.
a) Fiierul 51_iii_a.cpp conine programul care realizeaz citirea
formei funciei, compilarea i execuia programului care calculeaz valoarea
funciei.

#include<stdlib.h>
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
void main()
{ char s1[213]="return(";
char s2[]="double f(double x)\r\n\{\r\n";
FILE *f; int n,i,j;
f=fopen("functie.cpp","w");
fputs(s2,f);
printf("functia f(x)="); gets(&s1[7]);
strncat(s1,");\r\n}",6);
fputs(s1,f);
fclose(f);
system("bcc -Id;\borlandc\include -Ld:\borlandc\lib 51_iii_b.cpp>>
tmp.txt");
execl("51_iii_b ",NULL);}

b) Fiierul 51_iii_b conine programul care citete punctul x,
calculeaz valoarea funciei n acest punct i o afieaz.

#include<stdio.h>
#include<conio.h>
#include<math.h>
#include"functie.cpp"
void main()
{double x;
printf("x=");scanf("%lf",&x);
printf("f(%7.2lf)=%7.2lf",x,f(x));
getch();}


9.3 Particulariti ale algoritmilor de prelucrare
cu fiier conductor


Caracteristica general a algoritmilor de prelucrare cu fiier conductor
este parcurgerea secvenial a fiierului conductor i efectuarea unor prelucrri n
funcie de fiecare articol citit din acesta. Problema care se pune este detectarea
sfritului de fiier. Modul n care se realizeaz acest lucru n Pascal difer radical
de cel din C. n Pascal, funcia eof realiza prima etap a citirii (transferul datelor
tiina nvrii unui limbaj de programare. Teorie

din fiier n buffer) i de aceea trebuia apelat nainte de citirea efectiv. n C,
macrodefiniia feof nu face dect s furnizeze valoarea indicatorului de sfrit de
fiier, care este setat de operaia de citire; n program, citirea trebuie s apar
naintea verificrii sfritului de fiier. Forma general a algoritmului n cele dou
limbaje este:

Pascal:
while not eof(f) do
begin <citire articol>
<prelucrare articol citit>
end;
C:
<citire articol>
while(!feof(f))
{ <prelucrare articol citit>
<citire articol>}

Exemplu:
Crearea i consultarea unui fiier text care memoreaz elemente ntregi,
folosind funcia feof pentru gestionarea sfritului de fiier. La crearea fiierului,
fiier conductor este fiierul standard de intrare. La afiare, conductor este fiierul f.

#include<stdio.h>
#include<conio.h>
void main()
{ FILE *f;
int x; long dim;
clrscr(); f=fopen("numere.dat","w+");
scanf("%d",&x);
while(!feof(stdin))
{fprintf(f,"%d\n",x); scanf("%d",&x);}
fseek(f,0,SEEK_SET);
fscanf(f,"%d",&x);
while(!feof(f))
{printf("%d\t",x);
fscanf(f,"%d",&x);}
fclose(f);
getch();}

Acelai exemplu, folosind fiier binar:

#include<stdio.h>
#include<conio.h>
void main()
{ FILE *f;
int x,g; long dim;
clrscr(); f=fopen("numere.dat","wb+");
scanf("%d",&x);
while(!feof(stdin))
{fwrite(&x,sizeof(x),1,f);
scanf("%d",&x);}
fseek(f,0,SEEK_SET);
fread(&x,sizeof(x),1,f);
while(!feof(f))
{printf("%d\t",x);
fread(&x,sizeof(x),1,f);}
fclose(f);
c=getch();}