Sunteți pe pagina 1din 15

CAPITOLUL 8

Fiiere

FIIERE
8.1. Caracteristicile generale ale fiierelor 8.2. Deschiderea unui fiier 8.3. nchiderea unui fiier 8.4. Prelucrarea fiierelor text 8.4.1. Prelucrarea la nivel de caracter 8.4.2. Prelucrarea la nivel de cuvnt

8.4.3. Prelucrarea la nivel de ir de caractere 8.4.4. Intrri/ieiri formatate 8.5. Intrri/ieiri binare 8.6. Poziionarea ntr-un fiier 8.7. Funcii utilitare pentru lucrul cu fiiere 8.8. Alte operaii cu fiiere

8.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
113

CAPITOLUL 8

Fiiere

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.

8.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:

114

CAPITOLUL 8

Fiiere

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

CAPITOLUL 8

Fiiere

8.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). 8.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. 8.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.

116

CAPITOLUL 8

Fiiere

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

8.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; 117

CAPITOLUL 8 tab[i]=getw(pf);

Fiiere

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


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

8.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) {

118

CAPITOLUL 8

Fiiere

} fclose(pfsir);}

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

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

8.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 8.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
119

CAPITOLUL 8

Fiiere

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

8.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).
120

CAPITOLUL 8

Fiiere

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). void rewind(FILE *flux_date); Poziioneaz indicatorul la nceputul fluxului de date specificat ca argument (prototip n stdio.h).

Funcia rewind

8.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).

121

CAPITOLUL 8

Fiiere

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

8.8. 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).

122

CAPITOLUL 8

Fiiere

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

CAPITOLUL 8

Fiiere

- 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'; 124

CAPITOLUL 8 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); }

Fiiere

125

CAPITOLUL 8 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); }

Fiiere

NTREBRI I EXERCIII
Chestiuni practice Scriei un program de tiprire a coninuturilor mai multor fiiere, ale cror nume se transmit ca parametri ctre funcia main. Tiprirea se face pe ecran (lungimea paginii = 22) sau la imprimant (lungimea paginii = 61). Coninutul fiecrui fiier va ncepe pe o pagin nou, cu un titlu care indic numele fiierului. Pentru fiecare fiier, paginile vor fi numerotate (cu ajutorul unui contor de pagini). 2. Scriei un program care citete un fiier text. Pornind de la coninutul acestuia, se va crea un alt fiier, prin nlocuirea spaiilor consecutive cu unul singur. Se vor afia pe ecran coninutul fiierului de la care s-a pornit i coninutul fiierului obinut.
1. 126

CAPITOLUL 8

Fiiere

3. S se consulte coninutul unui fiier i s se afieze urmtoarele informaii statistice: numrul de cuvinte din fiier, numrul de caractere, numrul de linii, numrul de date numerice (nu cifre, numere!). 4. Scriei un program care s compare coninutul a dou fiiere, i afiai primele linii care difer i poziia caracterelor diferite n aceste linii. 5. Scriei un program care citete coninutul unui fiier surs scris n limbajul C i afieaz n ordine alfabetic fiecare grup al numelor de variabile care au primele n caractere identice (n este citit de la tastatur). 6. Scriei un program care consult un fiier text i afieaz o list a tuturor cuvintelor din fiier. Pentru fiecare cuvnt se vor afia i numerele liniilor n care apare cuvntul. 7. Scriei un program care citete un text introdus de la tastatur i afieaz cuvintele distincte, n ordinea cresctoare a frecvenei lor de apariie. La afiare, fiecare cuvnt va fi precedat de numrul de apariii. 8. Scriei un program care citete un text introdus de la tastatur, ordoneaz alfabetic liniile acestuia i le afieaz. 9. Scriei o aplicaie pentru gestiunea informatiilor despre crile existente ntr-o bibliotec. Aplicaia va avea un meniu principal care va permite: a) Memorarea datelor ntr-un fiier (un fiier binar cu structuri), al crui nume se introduce de la tastatur. Fiierul va contine informaiile: nume carte, autor, editura, anul apariiei, pre. Pentru fiecare carte, se va genera o cot (un numr unic care s constituie cheia de cutare). b) Adaugrea de noi cri; c) Afiarea informaiilor despre o anumit carte; d) Cutarea titlurilor dup un anumit autor; e) Modificarea informaiilor existente; f) Lista alfabetic a tuturor autorilor; g) tergerea unei cri din bibliotec; h) Ordonarea descresctoare dup anul apariiei; i) Numele celei mai vechi cri din bibliotec; j) Numele celei mai scumpe cri din bibliotec; k) Numele autorului cu cele mai multe cri; l) Valoarea total a crilor din bibliotec.

127

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