Sunteți pe pagina 1din 41

Fiiere generalitati.

Fiier = colecie ordonat de articole (nregistrri)


pstrate pe un suport extern de memorie i identificate
printr-un nume.
Fiierul standard de intrare cu date introduse de la
tastatur.
Fiierul standard de ieire -cu rezultate afiate pe
terminalul standard de ieire.
Fiierul standard de eroare - afiseaza mesajele de
eroare.
Sfritul fiierului este marcat printr-un indicator special
(Ctrl-Z in DOS, Ctrl-D in Unix)
Operatii cu fisiere.
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
FILE
Funciile de pe nivelul superior nu asigur o
independen total fa de sistemul de operare.
Funciile standard de intrare / ieire au
prototipurile n fiierul antet <stdio.h>.
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 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.
La fiierele binare, marcajul de sfrit de fiier nu
exist fizic n fiier, ci este generat de funcia
fgetc().
Redirectarea fisierelor.
In Unix (si in DOS), intrrile i ieirile standard pot fi
redirectate n fiiere disc, fr a opera nici o
modificare la nivelul programului.
< redirecteaz intrarea standard ctre fiierul
specificat
> redirecteaz ieirea standard ctre fiierul
specificat
con consola sistem (tastatura sau ecranul)
prn imprimanta paralel
com1 interfaa serial de date
nume_fiier un fiier disc
Accesul la fisiere.
Fiierele sunt gestionate prin pointeri la structuri FILE,
asociate fiierelor pe durata prelucrrii.
Fiierele standard au pointerii predefinii: stdin,
stdout, stderr, stdprn, stdaux.
Declararea unui pointer la fiier : FILE *pf;
1. deschiderea unui fiier
. asociaz unui nume de fiier un pointer la fiier
. stabilete un mod de acces la fiier
Pentru deschiderea unui fiier se folosete funcia
FILE *fopen(char *nume_fisier,
char *mod_acces);
Deschiderea unui fisier.
Deschiderea unui fiier
stabileste o conexiune logic ntre fiier i
variabila pointer
aloc o zon de memorie pentru realizarea mai
eficient a operaiilor de intrare / ieire
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
Inchiderea unui fiier
int fclose(FILE *pf);
ntoarce 0 la nchidere normal i EOF la
producerea unui incident
fiierele standard nu se nchid de ctre
programator
pentru un 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
Operatii de intrare / iesire.
Tip Conversie Unitate Functii
fisier transferata folosite
caracter fgetc()
fara fputc()
text linie fgets()
fputs()
cu linii fscanf()
fprintf()
binar fara articol fread()
fwrite()
Operaii de intrare / ieire la nivel de caracter
int fputc(int c, FILE *pf);
scrie un caracter in fisier
int fgetc(FILE *pf);
ntoarce urmtorul caracter citit din fiier, convertit
n ntreg sau EOF dac s-a citit sfrit de fiier
Exemplul 1: Scriei un program care copiaza un
fiier. Numele celor doua fiiere (surs i
destinaie) sunt citite de la terminal.
Copierea se face caracter cu caracter.
Exemplul 1: Copierea unui fisier
void copiere1(FILE *, FILE *);
int main(){
char numes[12], numed[12];
gets(numes);
gets(numed);
s = fopen(numes,r);
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);
}
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
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
Exemplul 2: Copierea unui fisier.

Exemplul 2: Sa se copieze un fiier folosind funcii


orientate pe iruri de caractere.

#define MAX 100


void copiere2(FILE *d, FILE *s){
char linie[MAX];
while(fgets(linie, MAX, s))
fputs(linie, d);
}
Moduri de acces la fisier.
1. fiierul nu exist; dorim s-l creem i s punem informaii n el
w - deschidere pentru scriere, noile scrieri se fac peste cele
vechi
2. 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 creat
4. fiierul exist deja; dorim s punem alte informaii n el
tergnd pe cele existente
w+ - citire i scriere; dac fiierul exist deja el este ters
Operaii de intrare / ieire 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 format are forma:
%[indicator][lime][.precizie]
[spec_lung]descriptor;
- aliniere stnga
+ afiare numere cu semn
0 completare stnga cu zerouri
Operaii de intrare / ieire cu format
Precizia este un numr interpretat diferit n funcie
de descriptorul folosit.
%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 short l long L 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.
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
Intrri / ieiri n modul de acces binar
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.
Exemplul 3: Copierea unui fisier nin mod binar.

void copiere(FILE * d, FILE * s)


{
int noc; // numar de octeti cititi
char zona[MAX];
while((noc=fread(zona,1,MAX,s))>0)
fwrite(zona, 1, noc, d);
}
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.
Poziionarea n fiier
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
Exemplul 4: Dimensiunea unui fisier.
long FileSize(FILE *pf)
{ long pozv, noct;
pozv = ftell(pf);//salvare poz crta
//pozitionare la sfarsit
fseek(pf, 0L, SEEK_END);
noct = ftell(pf); // nr de octeti
//revenirea la pozitia veche
fseek(pf, pozv, SEEK_SET);
return noct;
}
Tratarea erorilor
int 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
Exemplul 5: Actualizarea stocurilor
Fiierul comenzi.dat conine articole structuri cu
cmpurile:
-denumire produs- un ir de 20 de caractere
-cantitate comandat o valoare real.
Fiierul depozit.dat format din articole cu cmpurile:
- denumire produs un ir de 20 de caractere
- stoc i stoc_minim valori reale
- pre unitar valoare real
S se actualizeze fiierul 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.
Exemplul 5: Actualizarea stocurilor
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 <stdio.h>
#include <stdlib.h>
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;
Exemplul 5: Actualizarea stocurilor
int main()
{ 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\n);
exit(1);
};
Exemplul 5: Actualizarea stocurilor
if(!(fd=fopen(depozit.dat,r+b))){
fprintf(stderr,eroare depozit\n);
exit(1);
};
ff=fopen(facturi.dat,wb);
fc1=fopen(com1.dat,wb);
fc2=fopen(com2.dat,wb);
// ciclu procesare comenzi
Exemplul 5: Actualizarea stocurilor
while(1) {
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), 1);
Exemplul 5: Actualizarea stocurilor
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);
}
Exemplul 5: Actualizarea stocurilor

fclose(fc);
fclose(fd);
fclose(ff);
fclose(fc1);
fclose(fc2);
}
Exemplul 6
Scrieti un program prog.c, care va fi lansat
in executie prin comanda
prog [+-][n][LCB] fisier
valori
implicite + 10 L
Oricare din elementele primului argument
poate lipsi, caz in care se considera o
valoare implicita.
Programul scrie n unitati din fisierul
argument 2 la unitatea standard de iesire.
Exemplul 6
O unitate poate reprezenta:
o linie (L)
un caracter (C)
un bloc (B = 512 caractere)
Se vor afisa primele (+) sau ultimele (-) n unitati din fisier.
Exemple:
prog date.txt afiseaza primele 10 linii din fisier
prog date.txt afiseaza ultimele 10 linii din fisier
prog -25C date.txt afiseaza ultimele 25 de
caractere din fisier
prog +3B date.txt afiseaza primele 3 blocuri din
fisier
Exemplul 6
#include <stdio.h>
#include <ctype.h>
long posback(FILE *f, int n);
int nrlin(FILE *f);
long nrcar(FILE *f);
int main(int na, char** va)
{ enum mod{lin, car, bloc};
enum poz{fata, spate};
enum mod m;
enum poz p=fata;
FILE *f;
char linie[80];
int n=10;
int i, c;
Exemplul 6
//daca cda are 1 param.(nume fisier) se deschide
//fisierul, se citesc 10 linii care se afiseaza
if(na==2)
{ f=fopen(va[1],"r");
for(i=0; i<n; i++)
{ fgets(linie,80,f);
fputs(linie,stdout);
}
}
else
//se preia din parametru pozitia(fata/spate)
{ f=fopen(va[2],"r");
p=fata;
if(*va[1]=='-')
p=spate;
if(*va[1]=='+' || *va[1]=='-')
va[1]++; //caracterul urmator
Exemplul 6
// extrage contor
n=0;
while(isdigit(*va[1]))
{ n=10*n+(*va[1]-'0');
va[1]++;
}
if(n==0)
n=10;
//preluare tip unitate(car, bloc,linie)
if(*va[1]=='L')
m=lin;
else if(*va[1]=='C')
m=car;
else if(*va[1]=='B')
m=bloc;
Exemplul 6
else
m=lin;
if(m==lin)
{ if(p==spate)
fseek(f,posback(f,n),0);
for(i=0; i<n; i++)
{ fgets(linie,80,f);
fputs(linie, stdout);
}
}
else
{ if(m==bloc)
n*=512;
if(p==spate)
fseek(f, -n, 2);
Exemplul 6
else
fseek(f, 0, 0);
for(i=0; i<n; i++)
{
c=fgetc(f);
fputc(c,stdout);
}
}
}
}
Exemplul 6
//pozitia celei de-a n a linie din spate
long posback(FILE *f, int n)
{ int n1, c, i;
n1=nrlin(f);
char linie[80];
//ne mutam peste n1-n linii
fseek(f, 0, 0);
if(n1>n)
{ for(i=0; i<n1-n;i++)
fgets(linie,80,f);
}
return ftell(f);
}
Exemplul 6
//numar de linii din fisier
int nrlin(FILE *f)
{
int nl=0;
char linie[80];
long p=ftell(f);
rewind(f);
while(fgets(linie,80,f))
nl++;
fseek(f, p, 0);
return nl;
}
Exemplul 6
//numar de caractere din fisier
long nrcar(FILE *f)
{
long p, nc=0;
int c;
p=ftell(f);
rewind(f);
while((c=fgetc(f))!=EOF)
nc++;
fseek(f, p, 0);
return nc;
}