Fisiere in C si C++

16
Fişiere in C si C++ 1. Operaţii de intrare / ieşire. In limbajul C nu există instrucţiuni de intrare / ieşire. Operaţiile de intrare / ieşire sunt realizate prin apelul unor funcţii ale sistemului de operare. Acestea sunt implementate prin funcţii, sub o formă compatibilă pentru diversele sisteme de operare (sunt portabile). Un fişier este o colecţie ordonată de articole (înregistrări) păstrate pe un suport extern de memorie şi identificate printr-un nume. Pentru fişierul standard de intrare , datele sunt introduse de la tastatură. Pentru fişierul standard de ieşire , rezultatele sunt afişate pe terminalul standard de ieşire. Mesajele de eroare se afişează în fişierul standard de eroare . Fişierul are un articol care marchează sfârşitul fişierului. Pentru fişierul standard de intrare de la tastatură, sfârşitul de fişier, pentru sistemele de operare DOS şi Windows se generează prin Ctrl-Z (pentru Unix – prin Ctrl-D). Operaţiile specifice prelucrării fişierelor sunt. deschiderea unui fişier închiderea unui fişier creerea unui fişier citirea de articole din fişier (consultarea fişierului) actualizarea (sau modificarea) fişierului adăugare de articole la sfârşitul fişierului poziţionarea în fişier. ştergerea unui fişier schimbarea numelui unui fişier Prelucrarea fişierelor se face pe două niveluri: - nivelul inferior, care apelează direct la sistemul de operare. - nivelul superior, care utilizează structuri speciale FILE Funcţiile de pe nivelul superior nu asigură o independenţă totală faţă de sistemul de operare. Funcţiile standard de intrare / ieşire au prototipurile în fişierul antet <stdio.h>. 2. Fişiere text şi fişiere binare Într-un fişier text, toate datele sunt memorate ca şiruri de caractere, organizate pe linii, separate între ele prin marcajul sfârşit de linie ‘\n’ . Într-un fişier text spaţiul de memorare pe disc nu este folosit în mod eficient pentru datele numerice (astfel întregul 12345 ocupă 5 octeţi). Într-un fişier binar, datele sunt păstrate în formatul lor intern (2 octeţi pentru int, 4 octeţi pentru float, etc).

description

sda

Transcript of Fisiere in C si C++

Fiiere in C si C++

Fiiere in C si C++1. Operaii de intrare / ieire.

In limbajul C nu exist instruciuni de intrare / ieire. Operaiile de intrare / ieire sunt realizate prin apelul unor funcii ale sistemului de operare. Acestea sunt implementate prin funcii, sub o form compatibil pentru diversele sisteme de operare (sunt portabile).

Un fiier este o colecie ordonat de articole (nregistrri) pstrate pe un suport extern de memorie i identificate printr-un nume.

Pentru fiierul standard de intrare , datele sunt introduse de la tastatur.

Pentru fiierul standard de ieire , rezultatele sunt afiate pe terminalul standard de ieire.

Mesajele de eroare se afieaz n fiierul standard de eroare .

Fiierul are un articol care marcheaz sfritul fiierului. Pentru fiierul standard de intrare de la tastatur, sfritul de fiier, pentru sistemele de operare DOS i Windows se genereaz prin Ctrl-Z (pentru Unix prin Ctrl-D).

Operaiile specifice prelucrrii fiierelor sunt.

deschiderea unui fiier

nchiderea unui fiier

creerea unui fiier

citirea de articole din fiier (consultarea fiierului)

actualizarea (sau modificarea) fiierului

adugare de articole la sfritul fiierului

poziionarea n fiier.

tergerea unui fiier

schimbarea numelui unui fiier

Prelucrarea fiierelor se face pe dou niveluri:

nivelul inferior, care apeleaz direct la sistemul de operare.

nivelul superior, care utilizeaz structuri speciale FILEFunciile de pe nivelul superior nu asigur o independen total fa de sistemul de operare.

Funciile standard de intrare / ieire au prototipurile n fiierul antet .2. Fiiere text i fiiere binare

ntr-un fiier text, toate datele sunt memorate ca iruri de caractere, organizate pe linii, separate ntre ele prin marcajul sfrit de linie \n .

ntr-un fiier text spaiul de memorare pe disc nu este folosit n mod eficient pentru datele numerice (astfel ntregul 12345 ocup 5 octei).

ntr-un fiier binar, datele sunt pstrate n formatul lor intern (2 octei pentru int, 4 octei pentru float, etc).

La fiierele text marcajul de sfrit de fiier (caracterul 0X1A) exist fizic n fiier. La ntlnirea acestui caracter funcia fgetc() ntoarce EOF (-1). Marcajul de sfrit de fiier se genereaz de la tastatur prin Ctrl-Z.

n cazul fiierelor binare, marcajul de sfrit de fiier nu exist fizic n fiier, ci este generat de funcia fgetc().n MSDOS (i n Unix), la nivelul liniei de comand intrrile i ieirile standard pot fi redirectate n fiiere disc, fr a opera nici o modificare la nivelul programului. Astfel:

< redirecteaz intrarea standard ctre fiierul specificat

> redirecteaz ieirea standard ctre fiierul specificat

Fiierul standard de eroare nu poate fi redirectat.

Fiierul specificat poate fi:

con pentru consola sistem (tastatura, respectiv ecranul)

prn pentru imprimanta paralelcom1 pentru interfaa serial de datenume_fiier pentru un fiier discNUL pentru perifericul nul.

Exemple:

> test.exe > prn redirecteaz ieirea programului la imprimant> test.exe < f1.dat > f2.dat redirecteaz att intrarea ct i ieirea programului

3. Accesul la fiiere.

Fiierele disc i fiierele standard sunt gestionate prin pointeri la structuri specializate FILE, care se asociaz fiecrui fiier pe durata prelucrrii.

Fiierele standard au pointerii predefinii: stdin, stdout, stderr, stdprn, stdaux.

Declararea unui pointer la fiier se face prin:

FILE *pf;

1. deschiderea unui fiier:nainte de a fi prelucrat, un fiier trebuie s fie deschis. Prin deschidere:

se asociaz unui nume de fiier un pointer la fiier se stabilete un mod de acces la fiier

Pentru deschiderea unui fiier se folosete funcia cu prototipul:

FILE *fopen(char *nume_fisier, char *mod_acces);

Prin deschiderea unui fiier se stabilete o conexiune logic ntre fiier i variabila pointer i se aloc o zon de memorie (buffer) pentru realizarea mai eficient a operaiilor de intrare / ieire. Funcia ntoarce:

un pointer la fiier, n caz c deschiderea fiierului se face n mod corect

NULL dac fiierul nu poate fi deschis.

Vom considera mai nti dou moduri de acces :

citire (sau consultare) r citirea dintr-un fiier inexistent va genera eroare

scriere (sau creare) w - dac fiierul exist deja, el va fi ters

Fiierele standard nu trebuiesc deschise.

Redirectarea unui fiier deschis poate fi realizat cu:

FILE* freopen(char* nume, char* mod, FILE* flux));

Fiierul deschis este nchis i este deschis un nou fiier avnd ca surs fluxul, numele i modul de acces specificai ca parametri. O utilizare important o constituie redirectarea fluxului standard de intrare: datele vor fi citite din fiierul specificat, fr a face nici o modificare n program.

2. nchiderea unui fiier

Dup terminarea prelucrrilor asupra unui fiier, acesta trebuie nchis. Un fiier este nchis automat la apelarea funciei exit().int fclose(FILE *pf);

funcia ntoarce 0 la nchidere normal i EOF la producerea unui incident

fiierele standard nu se nchid de ctre programator

n cazul unui fiier de ieire, se scriu datele rmase nescrise din buffer n fiier, aa c operaia de nchidere este obligatorie

n cazul unui fiier de intrare, datele necitite din bufferul de intrare sunt abandonate

se elibereaz bufferele alocate

se ntrerupe conexiunea pointer fiier

Secvena urmtoare deschide un fiier cu un nume dat i apoi l nchide.

FILE *pf = fopen(test1.dat, w);

fclose(pf);

4. Operaii de intrare ieire.

Tip fiierConversieUnitate transferatFuncii folosite

TextfrCaracterfgetc(), fputc()

Liniefgets(), fputs()

cuLiniifscanf(). fprintf()

binarfrArticol (structur)fread(), fwrite()

4.1. operaii de intrare / ieire la nivel de caracter

Scrierea unui caracter ntr-un fiier se face folosind funcia:

int fputc(int c, FILE *pf);

Funcia ntoarce primul parametru sau EOF, n caz de eroare.

Citirea unui caracter dintr-un fiier se face cu funcia:

int fgetc(FILE *pf);

Funcia ntoarce ca rezultat urmtorul caracter citit din fiier, convertit n ntreg fr semn sau EOF dac s-a citit sfrit de fiier sau s-a produs o eroare la citire.

Scriei un program care realizeaz copierea unui fiier. Numele celor doua fiiere (surs i destinaie) sunt citite de la terminal.

#include

/* copierea unui fisier */

void copiere1(FILE *, FILE *);

void main(void){

char numes[12], numed[12];

gets(numes);

gets(numed);

FILE* s = fopen(numes,r);

FILE* d = fopen(numed,w);

copiere1(d, s);

fclose(s);

fclose(d);

}

void copiere1(FILE *d, FILE *s) {

int c;

while ((c=fgetc(s)) != EOF)

fputc(c, d);

4.2. }4.3. operaii de intrare / ieire pentru iruri de caractere

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

citete caractere din fiierul cu pointerul pf, pn la ntlnirea primului caracter \n (cel mult n-1 caractere) n tabloul s; pune la sfrit \n i \0 ntoarce s sau NULL la ntlnire sfrit de fiier sau la eroare

Scriei o funcie care simuleaz funcia fgets().

char *fgets(char *s, int n, FILE *pf) {

char c;

char *psir = s;

while (--n > 0 &&(c=fgetc(pf))!=EOF)

if((*psir++=c)==\n)

break;

*psir=\0;

return (c==EOF && psir==s) ? NULL: s;

}

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

copiaz irul n fiierul de ieire

nu copiaz terminatorul de ir \0 ntoarce un rezultat nenegativ (numrul de caractere scrise n fiier), sau EOF la producerea unei erori

Scriei o funcie care simuleaz funcia fputs().

int fputs(char *s, FILE *pf)

{ int c, n=0;

while (c = *s++){

fputc(c, pf);

n++;

}

return (ferror(pf)) ? EOF: n;

}

Copierea unui fiier folosind funcii orientate pe iruri de caractere are forma:

#define MAX 100

void copiere2(FILE *d, FILE *s){

char linie[MAX];

while(fgets(linie, MAX, s))

fputs(linie, d);

}

Revenim acum asupra modurilor de acces la disc. Sunt posibile urmtoarele situaii:

1. fiierul nu exist; dorim s-l creem i s punem informaii n el

w - deschidere pentru scriere, noile scrieri se fac peste cele vechi2. fiierul exist deja; dorim s extragem informaii din el

r - deschidere pentru citire, fiierul trebuie s existe deja r+ - citire i scriere ; fiierul trebuie s existe

3. fiierul exist deja; dorim s adugm informaii la el, pstrnd informaiile deja existente

a - deschidere pentru adugare, toate scrierile se adaug la sfritul fiierului existent sau nou creat a+ - citire i adugare; dac fiierul nu exist, el va fi creat4. fiierul exist deja; dorim s punem alte informaii n el tergnd pe cele existente

w+ - citire i scriere; dac fiierul exist deja el este tersModul de acces binar se specific cu sufixul b. Astfel avem: rb, w+bModul text este considerat implicit, dar poate fi specificat explicit prin t.4.3. operaii de intrare / ieire cu format

scrierea cu format

int fprintf(FILE *pf, char *format, lista_expresii);

transfer n fiierul specificat, valorile expresiilor, convertite, potrivit formatului n caractere

ntoarce numrul de caractere scrise, sau o valoare negativ, dac s-a produs o eroare.

Un descriptor de conversie din format ncepe prin % i poate avea un mai muli specificatori opionali, care preced descriptorul:

%[indicator][lime][.precizie][spec_lung]descriptor;

Indicatorul poate avea una din valorile:

- aliniere stnga

+ afiare numere cu semn

0 completare stnga cu zerouri

adaugare spaiu naintea primei cifre, dac numrul este pozitiv# %#o - scrie 0 iniial %#x - scrie 0x %#e,f,g,E,G scrie punctul zecimal i nu elimin zerourile la sfrit

Limea numr ce indic limea minim a cmpului n care se face scrierea.

* limea este dat de argumentul urmtor

Precizia este un numr interpretat diferit n funcie de descriptorul folosit.Astfel:%e, %E, %f numrul de cifre dup punctul zecimal%s numrul maxim de caractere afiate%g, %G numrul de cifre semnificative%d, %i numrul minim de cifre (cu zerouri n fa)

Specificarea lungimii se face prin:

H shortl longL long double citirea cu format

int fscanf(FILE *pf, char *format, lista_adrese_variabile);

se citesc date din fiierul pf, sub controlul formatului, iniializndu-se variabilele din list

funcia ntoarce numrul de cmpuri citite sau EOF n caz de producere a unui incident la citire sau ntlnire a marcajului de sfrit de fiier.

4.4. intrri / ieiri n modul de acces binar

sunt operaii de transfer (citiri / scrieri) fr conversii

se fac la nivel de articol

poziia n fiier este actualizat dup fiecare citire / scriere

unsigned fread(void *zona, unsigned la, unsigned na, FILE *pf);

citete cel mult na articole, de lungime la fiecare, din fiierul pf n zona

ntoarce numrul de nregistrri citite sau 0 n caz de eroare sau sfrit de fiier

unsigned fwrite(void *zona, unsigned la, unsigned na, FILE *pf);

scrie na articole de lungime la, din zona n fiierul pf ntoarce numrul de articole scrise.

Pentru a copia un fiier binar (sau text) folosind funciile fread() i fwrite() vom considera lungimea articolului 1 octet.

void copiere3(FILE * d, FILE * s) {

int noc; /* numarul de octeti cititi */

char zona[MAX];

while((noc=fread(zona, 1, MAX, s)) > 0)

fwrite(zona, 1, noc, d);

}

5. Operaii pentru fiiere cu acces direct.

5.1. Poziionarea n fiier

int fseek(FILE *pf, long depl, int orig);

modific poziia curent n fiierul cu pointerul pf cu depl octei relativ la cel de-al treilea parametru orig, dup cum urmeaz:

fa de nceputul fiierului, dac orig=0 (sau SEEK_SET) fa de poziia curent, dac orig=1 (sau SEEK_CUR)

fa de sfritul fiierului, dac orig=2 (sau SEEK_END)

ntoarce rezultatul 0 pentru o poziionare corect, i diferit de 0 n caz de eroare.

void rewind(FILE *pf);

realizeaz o poziionare la nceputul fiierului, fiind echivalent cu:

fseek(pf, 0L, SEEK_SET);

long ftell(FILE *pf);

ntoarce poziia curent n fiier, exprimat prin numrul de octei fa de nceputul fiierului

Scriei o funcie care determin numrul de octei ai unui fiier.

#include

long FileSize(FILE *pf)

{ long pozv, noct;

pozv = ftell(pf); /* salveaza pozitia curenta */

fseek(pf, 0L, SEEK_END); /* pozitionare la sfarsit */

noct = ftell(pf); /* numar de octeti din fisier */

fseek(pf, pozv, SEEK_SET); /*revenirea la pozitia veche*/

return noct;

} tratarea erorilorint feof(FILE *pf);

ntoarce o valoare diferit de 0, dac s-a detectat marcajul de sfrit de fiier

int ferror(FILE *pf);

ntoarce o valoare diferit de 0, dac s-a detectat o eroare n cursul operaiei de intrare / ieire

Fiierul comenzi.dat conine articole structuri cu cmpurile:

-denumire produs- un ir de 20 de caractere

-cantitate comandat o valoare real.

Fiierul depozit.dat este format din articole avnd cmpurile:

- denumire produs un ir de 20 de caractere

- stoc i stoc_minim valori reale

- pre unitar valoare real

S se actualizeze fiierul de stocuri, prin onorarea comenzilor. O comand este onorat, dac prin satisfacerea ei, stocul rmas n magazie nu scade sub stocul minim.

Se va creea un fiier facturi.dat, coninnd pentru fiecare comand onorat, denumirea produsului comandat i valoarea comenzii.

Se vor crea de asemeni dou fiiere, unul cu comenzi care nu au fost satisfcute, deoarece produsele erau n cantiti insuficiente, cellalt cu comenzi de produse care nu exist n depozit.

#include

#include

typedef struct { char den[20];

double cant;} comanda;

typedef struct { char den[20];

double stoc, stoc_min, pret;} depozit;

typedef struct { char den[20];

double val;} factura;

void main(void)

{ comanda com;

depozit dep;

factura fac;

double t;

int gasit, eof;

FILE *fc, *fd, *ff, *fc1, *fc2;

/* deschidere fisiere */

if((fc=fopen(comenzi.dat,rb))==NULL){

fprintf(stderr,eroare deschidere comenzi\n);

exit(1);

};

if((fd=fopen(depozit.dat,r+b))==NULL){

fprintf(stderr,eroare deschidere depozit\n);

exit(1);

};

ff=fopen(facturi.dat,wb);

fc1=fopen(com1.dat,wb);

fc2=fopen(com2.dat,wb);

while(1) { /* ciclu procesare comenzi */

if(!fread(&com, sizeof(com), 1, fc) break;

gasit=0;

rewind(fd);

do {

eof=fread(&dep, sizeof(dep), 1, fd)==0;

if(!eof) {

if(strcmp(com.den, dep.den)==0){

gasit = 1;

if((t=dep.stoc com.cant)>=dep.stoc_min) {

dep.stoc=t;

fseek(fd, -sizeof(dep), SEEK_CUR);

fwrite(&dep, sizeof(dep), 1, fd);

fac.val=com.cant * dep.pret;

strcpy(fac.den, com.den);

fwrite(&fac, sizeof(fac), 1, ff);

}

else

fwrite(&com, sizeof(com), 1, fc1);

break;

}

}

} while(!gasit && !eof);

if(!gasit)

fwrite(&com, sizeof(com), 1, fc2);

}

fclose(fc);

fclose(fd);

fclose(ff);

fclose(fc1);

fclose(fc2);

}

SemnturEfect

FILE* fopen(char* nume, char* mod);deschide fiierul; ntoarce pointerul la fiierul deschis sau NULL dac operaia eueaz

int fclose(FILE* pf);nchide fiierul

int fgetc(FILE* pf);citete 1 caracter din fiier ntoarce caracterul citit sau EOF

int fputc(char c, FILE* pf);scrie caracterul n fiier

char* fgets(char* s, int n, FILE* pf);citete din fiier n s cel mult n-1 caractere,sau pn la ntlnire \n, n locul cruia pune \0. ntoarce s sau NULL, dac s-a citit EOF.

int fputs(char* s, FILE* pf);copiaz irul n fiierul de ieire.nlocuiete terminatorul \0 cu \n.

int fscanf(FILE* pf, char* format, lista_adrese);citire din fiier sub controlul formatului. ntoarce numrul de cmpuri citite sau EOF, n caz de eroare sau sfrit de fiier.

int fprintf(FILE* pf, char* format, lista_expresii);scriere n fiier sub controlul formatului. ntoarce numrul de caractere scrise sau valoare negativ n caz de eroare.

int fread(char* zona, int la, int na, FILE* pf);citete din fiier n zona, na articole de lungime la fiecare.ntoarce numrul de articole efectiv citite.

int fwrite(char* zona, int la, int na, FILE* pf);scrie n fiier din zona, na articole de lungime la fiecare.ntoarce numrul de articole efectiv scrise.

int fseek(FILE* pf, long depl, int orig);poziionare cu depl octei fa de nceput, poziia curent sau sfritul fiierului

void rewind(FILE* pf);poziionare la nceputul fiierului

long ftell(FILE* pf);determin poziia curent n fiier.

int feof(FILE* pf);ntoarce nenul dac s-a detectat sfrit de fiier

int ferror(FILE* pf);ntoarce nenul dac s-a detectat o eroare n cursul operaiei de intrare / ieire

Fiiere n C++.

Realizarea funciilor de intrare/ieire n C++ se realizeaz prin intermediul fluxurilor (streamuri). Un flux este o clas.

Fluxurile pot fi clasificate n:

fluxuri de intrare/ieire standard

fluxuri de intrare/ieire folosind fiiere

fluxuri de intrare/ieire n memorie

n instruciunea cout .

Obiectele cin i cout sunt declarate n iostream.h.

Utilizatorul i definete propriile fluxuri, declarndu-le ca obiecte n clasele:

ofstream., pentru operaii de scriere

ifstream, pentru operaii de citire

fstream, pentru operaii att de citire, ct i de scriere

Pentru a folosi aceste clase trebuie inclus fiierul antet fstream.h .

Deschiderea unui fiier (asocierea fiier stream) se face cu funcia membru open(), avnd semntura:

void open(char* numefisier, int mod, int acces);

Modul n care poate fi deschis un fiier este precizat n clasa ios prin enumeratorii:

in

- fiierul se deschide pentru citire; fiierul trebuie s existe

out

- fiierul se deschide pentru scriere; dac exist se terge i se creaz un nou fiier

ate

- fiierul se deschide pentru adugare la sfrit, dac nu exist se creaz

app

- fiierul se deschide pentru adugare la sfrit; fiierul trebuie s existe

trunc

- dac fiierul exist, va fi ters i se va crea un fiier nou pentru scriere

nocreate- fiierul deschis trebuie s existe (el nu poate fi creat)

noreplace- fiierul este deschis, iar coninutul lui nu poate fi nlocuit

binary- fierul deschis va fi prelucrat ca un fiier binar

ifstream f;

f.open(note.dat, ios::in);

Modul de acces poate specifica una din valorile:

0 fiier fr restricii de acces

1 fiier protejat la scriere

2 fiier ascuns

4 fiier sistem

8 fiier arhiv

Desfacerea legturii fiier stream se face folosind funcia close().

Dac n urma deschiderii fiierului, variabila stream este egal cu NULL, atunci operaia de deschidere a euat.

ifstream f;

if(!f.open(note.dat, ios::in)){

cerr