Sunteți pe pagina 1din 7

CURS 10.

Operaii cu fiiere
Un fiier este o colecie de date de acelai tip, numite nregistrri, memorate pe suport extern ( hard disc,CD,... ).
Avantajele utilizrii fiierelor sunt o consecin a proprietilor memoriilor externe. Fiierele permit memorarea
unui volum mare de date persistente. Un fiier are o nregistrare care marcheaz sfritul de fiier. n cazul
fiierelor de intrare de la tastatur sfritul de fiier se genereaz prin CTRL+Z. El poate fi pus n eviden folosind
constanta simbolic EOF definit n stdio.h.
Prelucrarea fiierelor implic un numr de operaii specifice acestora. Orice fiier, nainte de a fi prelucrat, trebuie
s fie deschis. De asemenea la terminarea prelucrrii unui fiier acesta trebuie nchis.
Operaiile de deschidere nchidere se pot realiza prin intermediul unor funcii speciale de bibliotec.
Alte operaii frecvente:
- Crearea unui fiier;
- Actualizarea unui fiier;
- Poziionarea ntr-un fiier;
- Consultarea unui fiier;
- Adugarea de nregistrri ntr-un fiier;
- Stergerea unui fiier.
Sistemul de I/O din C separ printr-o anumit abstractizare programatorul de echipament. Forma abstract se
numete stream iar instrumentul efectiv care se poate utiliza este fiierul.
In C, conform standardului, se poate lucra cu fiiere fie la nivel binar, fie la nivel de caracter. Diferena const n
modul n care sunt tratate inregistrrile din fiier. Astfel, dac acestea sunt tratate la nivel de caracter, atunci
operaiile de IO se vor realiza prin utilizarea unor structuri de tipul ir de caractere, referite fie sub form de
variabile de tip ir de caractere (char[]) fie pointeri spre caractere (char*).
Dac accesul la fiier se face in mod binar, atunci datele se vor referi prin pointeri de tipul void*. Prin intermediul
acestora, practic se poate face referire la orice tip de dat din program. Astfel, fiierele tratate la nivel binar pot
salva date de orice tip. Evident, n comparaie cu tratarea fiierelor la nivel ir de caractere, nu avem un delimitator
de nregistrare (precum caracterul \0), astfel nct, la fiecare operaie de scriere / citire trebuie s se specifice
lungimea nregistrrii, adic numrul de octei scrii / citii.
Trebuie s remarcm faptul c limbajul de programare C unific modul de lucru cu fiierele. Astfel, intrrile /
ieirile sunt tratate unitar, fie c vorbim de fiiere de pe disc fie c vorbim despre dispozitivele standard de intrare /
ieire precum stdin, stdout sau stderr. Astfel, funciile de citire / scriere din dispozitivele standard, din fiiere sau
iruri de caractere precum scanf / fscanf / sscanf respectiv printf / fprintf / sprintf sunt realizate in mod unitar i au
utilizare similar.

10.1. Lucrul cu fiiere la nivel de iruri de caractere


Deschiderea unui fiier

La acest nivel se utilizeaz funcia fopen pentru deschiderea unui fiier. Ea returneaz un pointer spre tipul FILE
(tipul fiier), tip definit n fiierul stdio.h. In caz de eroare, funcia fopen returneaz pointerul NULL. Funcia fopen
realizeaz o alocare de memorie i returneaz zona de memorie alocat n cazul in care sistemul de operare
reueste s deschid fiierul specificat n modul de deschidere solicitat de funcie.
Prototipul funciei fopen este:
FILE *fopen(const char *cale, const char *mod);
unde:
1

cale
mod

reprezint calea pe disc a fiierului care se deschide.


este un pointer spre un ir de caractere care definete modul de prelucrare al fiierului
dup deschidere. Acest ir se definete n felul urmtor:

r
deschidere n citire (read); fiierul trebuie s existe.
w deschidere n scriere (write); se deschide un fiier gol. Dac fiierul deja exist pe disc, coninutul acestuia
este ters i se creaz un fiier nou
a
deschidere pentru adugare (append); datele vor fi scrise la finalul fiierului. Dac fiierul nu exist, atunci
acesta este creat.
r+ deschidere pentru modificare (citire sau scriere); fiierul trebuie s existe
w+ creaz un fiier gol pentru scriere / citire;
a+ deschide un fiier pentru citire i adugare.
Dac se deschide un fiier inexistent cu modul w sau a, atunci el este deschis n creare. Dac se deschide un
fiier existent cu modul w, atunci coninutul vechi al fiierului se pierde i se va crea unul nou cu acelai nume.
Menionm c stdin, stderr, stdaux i stdprn sunt pointeri spre tipul FILE i permit ca funciile de nivel superior de
prelucrare a fiierelor s poat trata intrarea standard i ieirile standard pe terminal i imprimant la fel ca i
fiierele pe celelelate suporturi. Singura deosebire const c aceste fiiere nu se deschid i nici se nchid de ctre
programator. Ele sunt deschise automat la lansarea n execuie a programului i se nchid la apelul funciei exit.
Variabilele stdin, stderr, stdaux i stderr exist n program ca i variabile globale, iar declaraiile lor sunt introduse
prin stdio.h

Citire / scriere de caractere


Fiierele pot fi scrise i citite caracter cu caracter, folosind dou funcii simple i anume putc pentru scriere i getc
pentru citire. Funcia putc are prototipul:
int putc(int c, FILE *pf);
unde:
- c este codul ASCII al caracterului care se scrie in fiier;
- pf este pointerul spre tipul FILE a crui valoare a fost returnat de funcia fopen la deschiderea fiierului n
care se scrie. In particular, pf poate fi unul din pointerii:
stdout
(ieire standard);
stderr
(ieire pe terminal n caz de eroare);
stdaux
(comunicaie serial);
stdprn
(ieire paralel la imprimant).
Funcia putc returneaz valoarea lui c respectiv -1 n caz de eroare.
Funcia getc are prototipul
int getc(FILE *pf);
unde pf este pointerul spre tipul FILE a crui valoare a fost returnat de funcia fopen la deschiderea fiierului. Ea
returneaz codul ASCII al caracterului citit sau EOF la sfrit de fiier sau eroare. In particular, pf poate fi
pointerul stdin (intrare de la tastatur).
Similar cu acestea, sunt funciile fputc i fgetc.
Pentru lucrul cu intrarea / ieirea standard, se pot folosi funciile getchar sau putchar, cu sintax similar cu getc si
putc, fr s fie necesar transmiterea pointerului stdin sau stdout.

Inchiderea unui fiier


Dup terminarea prelucrrii unui fiier, acesta urmeaz a fi nchis. In acest caz se utilizeaz funcia fclose. Ea are
prototipul
int fclose(FILE *pf);
unde pf este pointerul spre tipul FILE a crui valoare a fost definit la deschiderea fiierului prin intermediul
funciei fopen. Funcia fclose returneaz:
0 la nchiderea normal a fiierului
EOF:
n caz de eroare.
Pentru toate fiierele deschise prin fopen trebuie s existe un apel fclose. fclose are 2 roluri:
- elibereaz resursele alocate la nivelul sistemului de operare
- elibereaz memoria alocat pentru pointerul de tip FILE* prin intermediul funciei fopn.
Exemplu. Programul copiaz intrarea standard la ieirea standard stdout, folosind funciile getc i putc.
#include <stdio.h>
int main() /* copiaza intrarea stdin la iesirea stdout */
{
int c;
while((c = getc(stdin)) != EOF) putc(c,stdout);
}

Exemplu. Programul scrie la ieirea stdout caracterele unui fiier a crui cale este argumentul din linia de comand
(pentru detalii n legtur cu parametrii transmii prin linia de comand). Dac nu exist un argument n linia de
comand, atunci se citete de la intrarea standard.
#include <stdio.h>
int main(int argc,char *argv[]) /* listeaza la ieirea stdout un fisier a carui cale este argumentul din linia de
comanda */
{
FILE *pf;
int c;
if(argc == 1) /* nu exista argument in linia de comanda */
pf = stdin;
else // se deschide fisierul a carui cale se afla n argv[ 1] //
if((pf = fopen( argv[1], "r"))==NULL) {
printf("nu se poate deschide fisierul %s/n",*argv);
return -1;
}
while((c = getc(pf)) != EOF )
putchar(c);
fclose(pf);
return 0;
}

Operaiile de intrare/ieire cu format


Biblioteca standard a limbajului C conine funcii care permit realizarea operaiilor de intrare/ieire cu format. Se
pot utiliza funciile fscanf i fprintf, prima pentru citire cu format dintr-un fiier, iar a doua pentru scriere cu format
ntr-un fiier.
3

Funcia fscanf este asemntoare cu funcia scanf. Ea are un parametru n plus fa de scanf, un pointer spre tipul
FILE care definete fiierul din care se face citirea. Acest pointer este primul parametru al funciei fscanf. Ceilali
parametri au aceeai semnificaie ca i n cazul funciei scanf.
Rezult c funcia fscanf poate fi apelat printr-o expresie de atribuire de forma
nr=fscanf(pf,control,par1, par2,...parn);
unde:
- pf este un pointer spre tipul FILE i valoarea lui a fost definit prin apelul funciei fopen (aceasta definete
fiierul din care se face citirea) iar ceilali parametri sunt identici cu cei utilizai la apelul funciei scanf .
Funcia fscanf, ca i scanf, returneaz numrul cmpurilor citite din fiier.
La ntlnirea sfritului de fiier se returneaz valoarea EOF definit n fiierul stdio.h. Pentru ps=stdin, functia
fscanf este identic cu scanf.
Funcia fprintf este analoag cu funcia printf. Primul ei parametru este un pointer spre tipul FILE i el definete
fiierul n care se scriu datele. Ceilali parametri sunt identici cu cei ai funciei printf.
Funcia fprintf, ca i funcia printf, returneaz numrul caracterelor scrise n fiier sau -1 n caz de eroare. Pentru
sf=stdout, funcia fprintf este identic cu printf. De asemenea, se pot utiliza pointerii standard obinuii:
stderr
- afiarea mesajelor de eroare pe terminal
stdaux
- comunicaie serial
stdprn
- ieirea paralel la imprimant.
Menionm c la comunicaia serial se poate conecta o imprimant serial.

Intrri/ieiri de iruri de caractere


Biblioteca standard a limbajului C conine funciile fgests i fputs care permit citirea respectiv scrierea ntr-un fiier
ale crui nregistrri sunt iruri de caractere.
Funcia fgets are prototipul
char *fgets(char *s, int n, FILE *pf);
unde:
- s este pointerul spre zona n care se face citirea caracterelor
- n-1 este numrul maxim de caractere care se citesc iar pf este pointerul spre tipul FILE care definete
fiierul din care se face citirea.
Citirea se incheie fie dac se citesc n-1 caractere, fie dac se ntlnete delimitatorul de sfrit de linie.
De obicei s este numele unui tablou de tip char de dimensiune cel puin n. s trebuie s fie alocat nainte de
inceperea execuie funciei fgets i trebuie s aib capacitatea de minim n octei.
Sirul se termin cu `\0` (caracterul NULL) care este inserat de funcia fgets la captul irului de caractere citit. La
ntlnirea caracterului `\n`, citirea se oprete. In acest caz, n zona receptoare se transfer caracterul `\n` i apoi
caracterul NULL. In mod normal, funcia returneaz valoarea pointerului s. La ntlnirea sfritului de fiier se
returneaz valoarea NULL.
Funcia fputs scrie ntr-un ir fiier un ir de caractere care se termin prin `\n`. Ea are prototipul
int fputs(const char *s,FILE *pf); unde:
- s este pointerul spre zona care conine irul de caractere care se scrie;
- pf este pointerul spre tipul FILE care definete fiierul n care se scrie.
Funcia fput returneaz codul ASCII al ultimului caracter scris sau -1 n caz de eroare.
Aceste funcii sunt realizate folosind funcia getc pentru fgets i putc pentru fputs.
4

10.2 Prelucrarea fiierelor binare


Fiierele organizate ca date binare (octeii nu sunt considerai ca fiind coduri de caractere) pot fi prelucrate la acest
nivel folosind funciile fread i fwrite.
In acest caz, se consider c nregistrarea este o colecie de date structurate numite articole. La o citire, se transfer
ntr-o zon special, numit zon tampon, un numr de articole care se presupune c au o lungime fix. In mod
analog, la scriere se transfer din zona tampon un numr de articole de lungime fix. Cele dou funcii au
prototipurile de mai jos:
size_t fread(void *ptr, size_t dim, size_t nrart, FILE *pf);
size_t fwrite(const void *ptr, size_t dim, size_t nrart, FILE *pf);

unde:
- ptr este pointerul spre zona tampon ce conine articolele citite / scrise (nregistrarea citit / scris);
- dim este un ntreg ce reprezint lungimea unui articol;
- nrart este un ntreg ce reprezint numrul articolelor care se transfer;
- pf este un pointer spre tipul FILE care definete fiierul din care se face citirea.
De obicei, dim este dimensiunea (sizeof) a tipului ctre care pointeaz pointerul ptr.
Ambele funcii returneaz numrul articolelor transferate sau -1 n caz de eroare.
Exemplu. Programul citete dde la intrarea stdin datele ale cror formate sunt definite mai jos i le scrie n fiierul
misc.dat din directorul curent. Formatul datelor de intrare este urmtorul:
Tip
denumire
I
REZISTENTA
#include <stdio.h>
#define MAX 50

val
010

um
KG

cod
12345678

pret
1.5

cantitate
10000.0

typedef struct {
char tip[2];
char den[MAX + 1];
int val;
char unit[3];
long cod;
float pret;
float cant;
} TIP_ARTICOL;
int cit(TIP_ARTICOL *str) //citeste datele de la intrarea standard si le scrie in structura spre care pointeaza str
{
int c,nr;
float x,y;
while((nr = scanf("%1s %50s %3d %2s %1d", str->tip, str->den, &str->val, str->unit, &str->cod))!= 5 ||
scanf("%f %f", &x, &y) != 2)
{
if(nr == EOF ) return EOF;
printf("rand eronat; se reia \n");
5

// avans pana la newline sau EOF


while((c = getchar()) != '\n' && c != EOF);
if(c == EOF) return EOF;
} //sfarsit while
str->pret = x; str->cant = y;
return nr;
} // sfarsit cit
int main() // creeaza fisierul misc.dat cu datele citite de la stdin
{
FILE *pf;
TIP_ARTICOL a[6];
int i, n;
if((pf = fopen("misc.dat","w+")) == NULL)
{
printf(" nu se poate deschide in creare fisierul misc.dat\n");
return -1;
}
for(i = 0; i < 6; i++) {
n = cit(&a[i]);
}
if( 6 != fwrite( &a, sizeof(TIP_ARTICOL), 6, pf)) {
// eroare la scrierea in fisier
printf("eroare la scrierea in fisier\n");
return -1;
}
fclose(pf);
// sfarsit main
return 0;
}
Exemplu. Programul listeaz articolele fiierului misc.dat, creat prin programul anterior, pentru care tip=I.
#include <stdio.h>
#define MAX 50
typedef struct {
char tip[2];
char den[MAX + 1];
int val;
char unit[3];
long cod;
float pret;
float cant;
} TIP_ARTICOL;
main()
{

/* citeste fisierul misc.dat

FILE
*pf;
int i,n;
TIP_ARTICOL
if((pf

*/

a[6];

= fopen("misc.dat","r")) == NULL) {
printf("nu se poate deschide fisierul misc.dat in citire\n");
return -1;

}
printf("%60s\n\n\n","INTRARI\n\n");
// se citeste o inregistrare
while((n = fread(a, sizeof(TIP_ARTICOL), 6, pf )) > 0)
// se listeaza articolele de tip I dintr-o inregistrare
for (i = 0; i < n; i++) {
if ( a[i].tip[0]
== 'I')
printf("%s
%3d %s %d %.2f
%.2f\n",
a[i].cod, a[i].pret, a[i].cant);
}
fclose(pf);
return 0;
}

a[i].den,

a[i].val,

a[i].unit,

Poziionarea ntr-un fiier


Biblioteca standard a limbajului C conine funcia fseek, cu ajutorul creia se poate deplasa capul de citire/scriere
al discului n vederea prelucrrii nregistrrilor fiierului ntr-o ordine oarecare, diferit de cea secvenial (acees
aleator). Ea are prototipul
int fseek(FILE *pf,long deplasament, int origine);
unde pf este pointerul spre tipul care definete fiierul n care se face poziionarea capului de citire/scriere iar
deplasament i origine au aceeai semnificaie ca i n cazul funciei lseek.
Funcia fseek returneaz valoarea zero la pozionare corect i o valoare diferit de zero n caz de eroare.
O alt funcie util n cazul accesului aleator este funcia ftell, care indic poziia capului de citire n fiier. Ea are
prototipul
long ftell(FILE *pf); unde:
- pf este pointerul spre tipul FILE care definete fiierul n cauz.
Funcia returneaz o valoare de tip long care definete poziia curent a capului de citire/scriere, i anume
reprezint deplasamentul n octei a poziiei capului fa de nceputul fiierului.

tergerea unui fiier


Un fiier poate fi ters apelnd funcia unlink. Aceasta are prototipul
int unlink(const char *cale);
unde cale este un pointer spre un ir de caractere identic cu cel utilizat la crearea fiierului n funcia de creat sau
fopen.
Funcia unlink returneaz valoarea zero la o tergere reuit, respectiv -1 n caz de eroare.

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