Documente Academic
Documente Profesional
Documente Cultură
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
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.
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
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);
// . . . deschidere fiier
while (!feof(pf)){ for (int i=0; i<100; i++){ if (feof(pf)) break; 117
CAPITOLUL 8 tab[i]=getw(pf);
Fiiere
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);
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 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
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).
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