Anda di halaman 1dari 7

Fisiere

Functii de I/E
Lucrul cu fisiere
Argumentele liniei de comanda
Exemple
Exercitii
Functii de I/E
O parte a puterii limbajului C consta in biblioteca de functii puse la dispozitia
programatorului. Declaratiile diferitelor functii sunt grupate in fisiere antet
(header).
Cateva din functiile si constantele cele mai des intilnite au fost deja utilizate
in exemplele anterioare.
stdio.h - contine functii de introducere - extragere a datelor
Functiile utilizate pina in acest moment (de ex: getchar, printf, gets, etc.)
opereaza cu fisierele standard de introducere si extragere: stdin(implicit
tastatura) si stdout (implicit monitorul). Prin redirectare aceste fisiere standard
se pot asocia cu alte fisiere.
Exemplu:
fisier_exe <fisier_1 >fisier_2
In acest caz preluarea informatiilor se face din fisier_1, iar afisarea
informatiilor de iesire se face in fisier_2.
Urmatoarele functii opereaza cu fisiere specificate de utilizator:
pentru un caracter:
int getc(FILE *fis);- returneaza un caracter din fisierul precizat convertit la un
intreg fara semn, iar la eroare returneaza EOF
int ungetc(int c, FILE *fis);- inapoiaza caracterul c in fisierul deschis pentru
citire
int putc(int c, FILE * fis); - trimite caracterul in fisierul deschis pentru
scriere, la eroare returneaza EOF
pentru un sir de caractere:
char *fgets(char *s, int n, FILE *fis);- citeste maxim n-1 caractere sau pina la
'\n' inclusiv, si le depune in s, adauga la sfirsit '\0' si returneaza adresa
sirului. La eroare intoarce valoarea NULL
int fputs(const char *s, FILE *fis); - scrie sirul in fisier, fara caracterul
'\0'. La eroare intoarce EOF.

pentru scriere si citire cu format:


int fscanf (FILE *fis, const char *format [, adresa, ...]); - numarul de adrese
trebuie sa corespunda cu numarul de specificatori de format. Formatul contine -
caractere spatii - se sare peste spatii pina la primul caracter nespatiu -
caractere obisnuite - caractere ASCII, mai putin '%', se trece peste un caracter
corespunzator in intrare
specificatorul de format: % [*] [width] type
* - se sare peste urmatoarea data
width - nr. de maxim de caractere ce se citesc
type - tipul informatiei citite:
o - octal , u - fara semn, x,X - hexa
d - zecimal, l - long, f - float, lf - double,
e,E- format stiintific, c - char, s - sir
int fprintf (FILE *fis, const char *format [, argum...]); - preia un sir de
argumente si le aplica formatul corespunzator, dupa care le scrie in fisierul
dat. Formatul contine - caractere obisnuite, care apar la fel la iesire
specificatori de format (egal sau mai mic decit numarul de
argumente): % [fanion] [width][.prec] type
fanion - alinierea la dreapta sau stinga, prezenta
semnului, etc.
width - numarul minim de caractere ce se afiseaza
prec - precizia
conio.h - functii de intrare, iesire pentru consola
void window(int left, int top, int right, int bottom);- defineste o fereastra text
precizata prin colturile stinga sus, dreapta jos
void clreol( void );- sterge intr-o fereastra text de la cursor pina la sfirsirul
liniei
void clrscr( void );- sterge fereastra text activa si muta cursorul in pozitia 1,1
void gotoxy( int x, int y );- muta cursorul la coordonatele date
int wherex( void );- returneaza coordonata curenta x
int wherey( void );- returneaza coordonata curenta y
int getch( void ); - citeste un caracter fara a-l afisa la consola
int getche( void ); - citeste si afiseaza caracterul
int kbhit( void ); - verifica daca a fost apasata o tasta
int putch( int c );- pune un caracter in fereastra text curenta.
stdlib.h - contine tipuri, variabile si functii uzuale
#define max(a,b) (((a) > (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
pentru conversia unui sir:
double atof(const char *s); - returneaza valoarea reala obtinuta prin conversia
sirului, iar la eroare valoarea 0
int atoi(const char *s); - converteste sirul la un intreg
long atol(const char *s); - converteste sirul la un long
pentru terminarea programului:
void exit(int status); - termina programul si inchide toate fisierele.
Parametrul status indica terminare normala (valoarea 0) sau anormala.
void abort(void);- termina anormal programul
pentru alocare dinamica:
void free(void *bloc);- elibereaza memorie alocata dinamic anterior
void *malloc(dim_t nr);- aloca nr locatii de memorie de cite sizeof(dim_t) octeti.
La succes returneaza adresa de inceput a zonei alocate, la eroare returneaza NULL
cautare binara:
void * bsearch(const void *key, const void *base, size_t nelem, size_t width, int
(*fcmp)(const void *, const void *));- returneaza adresa primei intrari din tablou
care coincide cu parametrul cautat si zero daca acesta nu exista in tablou. ( key-
adresa cheii cautate, base- inceputul tabloului, nelem- nr.elemente din tablou,
width- dim. unui elem. de tablou, fcmp- functia de comparare definita de utilizator
si care primeste doi parametrii )
sortare cu algorimul Quicksort:
void qsort(void *base, size_t nelem, size_t width, int (*fcmp)(const void *, const
void *));- sorteaza tabloul dat.

Lucrul cu fisiere
Un fisier este o structura dinamica, situata in memoria secundara ( pe flopyy disk-
uri sau harddisk-uri ); numarul de elemente ale unui fisier este variabil, chiar
nul..
Limbajul C permite operarea cu fisiere:
de tip text - un astfel de fisier contine o succesiune de linii, separate prin NL
('\n')
de tip binar - un astfel de fisier contine o succesiune de octeti, fara nici o
structura.
Prelucrarea unui fisier presupune asocierea acestuia cu un canal de I/E ( numit
flux sau stream ). Exista doua canale predefinite, care se deschid automat la
lansarea unui program:
stdin - fisier de intrare, text, este intrarea standard - tastatura
stdout - fisier de iesire, text, este iesirea standard - ecranul monitorului.
Pentru a prelucra un fisier, trebuie parcurse urmatoarele etape:
se defineste o variabila de tipFILE *pentru accesarea fisierului; FILE * este un
tip structura definit in stdio.h, care contine informatii referitoare la fisier si
la tamponul de transfer de date intre memoria centrala si fisier ( adresa, lungimea
tamponului, modul de utilizare a fisierului, indicator de sfarsit, de pozitie in
fisier )
se deschide fisierul pentru un anumit mod de acces, folosind functia de biblioteca
fopen, care realizeaza si asocierea intre variabila fisier si numele extern al
fisierului
se prelucreaza fisierul in citire/scriere cu functiile specifice
se inchide fisierul folosind functia de biblioteca fclose.
Mai jos se prezinta restul functiilor de prelucrare a fisierelor:
FILE *fopen(const char *nume_fis, const char *mod); - deschide fisierul cu numele
dat pentru acces de tip mod. . Returneaza pointer la fisier sau NULL daca fisierul
nu poate fi deschis; valoarea returnata este memorata in variabila fisier, care a
fost declarata pentru accesarea lui.
mod: "r" - readonly , este permisa doar citirea dintr-un fisier existent
"w" - write, creaza un nou fisier, sau daca exista deja, distruge
vechiul continut
"a" - append, deschide pentru scriere un fisier existent
( scrierea se va face in continuarea informatiei deja existente in fisier, deci
pointerul de acces se plaseaza la sfirsitul fisierului )
"+" - permite scrierea si citirea - actualizare (ex: "r+", "w+",
"a+"). O citire nu poate fi direct urmata de o scriere si reciproc. Intai trebuie
repozitionat cursorul de acces printr-un apel la fseek.
"b" - specifica fisier de tip binar
"t" - specifica fisier de tip text (implicit), la care se face
automat conversia CR-LF("\n\f") in sau din CR ('\n').
int fclose(FILE *fp);- inchide fisierul si elibereaza zona tampon; returneaza 0 la
succes, EOF la eroare
int fseek(FILE *fp, long offset, int whence);- repozitioneaza pointerul asociat
unui fisier . Offset - numarul de octeti intre pozitia data de whence si noua
pozitie. Whence - are una din cele trei valori posibile:
SEEK_SET = 0 - Cautarea se face de la inceputul fisierului
SEEK_CUR = 1 - Cautare din pozitia curenta
SEEK_END = 2 - Cautare de la sfirsitul fisierului
int feof(FILE *fis);- returneaza 0 daca nu s-a detectat sfarsit de fisier la ultima
operatie de citire, respectiv o valoare nenula ( adevarata ) pentru sfarsit de
fisier.

Argumentele liniei de comanda


La lansarea in executie a unui fisier executabil, in linia de comanda, pe langa
numele fisierului s epot specifica argumente, care se transmit ca parametrii
functiei main. Antetul functiei main va fi atunci:
int main( int argc, char ** argv )
argc - reprezinta numarul de argumente
argv -este un pointer la un tablou de siruri, reprezentand argumentele.
Argumentele liniei de comanda vor fi sirurile:
argv[0] - numele fisierului executabil
argv[1]
...
argv[argc-1]
Programul urmator tipareste argumentele liniei de comanda:

// fisier listare.c
#include<stdio.h>
int main( int argc, char** argv){
int i;
puts("Argumente:");
for(i=0;i<argc;i++)
puts(argv[i]);
return 0;
}
O linie de comanda de forma:
listare iata patru argumente
va lansa in executie listare.exe, care va tipari pe ecran:
listare.exe
iata
patru
argumente:

Exemple
1.Sa se scrie un program care copiaza continutul unui fisier in altul, numele
sursei si destinatiei fiind transmise in linia de comanda.

// fisier copiere.c
# include <stdio.h>
int main(int argc, char** argv){
FILE *fisi, *fise; char c;
if(!(fisi=fopen(argv[1],"r")||
!(fise=fopen(argv[2],"w")){
puts("Fisierele nu pot fi deschise");
return 1;
} //eroare daca fisierele nu pot fi deschise
while((c=fgetc(fisi))!=EOF) //copiere caracter cu caracter
fputc(fise);
fclose(fisi);
fclose(fise);
return 0;
}
Lansarea in executie a programului se va face cu o linie de comanda de forma:
copiere fisier_sursa.dat fisier_dest.dat
Folosind redirectarea fisierelor standard, printr-o linie de comanda de forma:
copiere1 <fisier_sursa.dat >fisier_dest.dat
urmatorul program va avea acelasi rezultat:

// fisier copiere1.c
# include <stdio.h>
void main(void){
char c;
while((c=getchar())!=EOF) //copiere caracter cu caracter
putchar(c);
return 0;
}
2.Sa se scrie un program care executa in mod repetat urmatoarele operatii:
Preia informatiile (nume si nota) pentru o grupa de studenti. Citirea se face
dintr-un fisier al carui nume se specifica de utilizator.
Verifica prezenta unui student in grupa
Listeaza grupa in ordine alfabetica si afiseaza media grupei.
Termina program.
# include <stdio.h>
# include <stdlib.h>
# include <ctype.h>
# include <string.h>
# define MAX_S 30
# define MAX_L 20
char stud[MAX_S][MAX_L];
FILE *fp=NULL;
int nrstud;
float medie;
void citire(FILE *fp, char tab[][MAX_L]){
float nota;
int i;
medie=0;
i=0;
while(!feof(fp)){
fscanf(fp,"%s%f",tab[i++],&nota);
medie+=nota;
}
nrstud=i-1;
medie/=nrstud;
qsort(tab,nrstud,MAX_L,strcmp);
}
int cauta(char *s, char tab[][MAX_L]){
char *t;
t=bsearch(s,tab,nrstud,MAX_L,strcmp);
return (t-tab)/MAX_L;
}
void main(){
char c,s[12];
int i;
while(1){
printf("\nOptiunea:\nCitire, Prezenta_student, Listare, Iesire\n >");
c=getchar();getchar();
switch(toupper(c)){
case 'C': printf("nume fisier:");gets(s);
if(fp!=NULL) fclose(fp);
if((fp=fopen(s,"r"))==NULL){
printf("fisierul %s nu exista\n",s);
break;
}
citire(fp,stud);
break;
case 'P': printf("nume student:");gets(s);
if((i=cauta(s,stud))<0)
printf("nu exista studentul %s in grupa",s);
else
printf("studentul %s este al %d-lea din grupa",s,i+1);
break;
case 'L': printf("Lista studenti:\n");
for(i=0;i<nrstud;i++)
printf("%d %s\n",i+1,stud[i]);
printf("\n\n media grupei = %4.2f\n\n",medie);
break;
case 'I': printf("terminare program\n");
fclose(fp);exit(0);
} /*switch*/
} /*while*/
}
3.Intr-un fisier de tip text sunt pastrate valorile reale ale unei masuratori sub
forma:
nr_masuratori '\n' val1 '\n' val2 '\n' val3 ...
Sa se scrie programul care afiseaza numarul de masuratori si valorile respective,
dupa care adauga la fisier noi masuratori pina la introducerea valorii 0. Valorile
citite se afiseaza in format stiintific.

# include <math.h>
# include <stdio.h>
# include <stdlib.h>
# define MAX 100
FILE *fp;
double masur[MAX],mas_noua;
char nume_fis[12],s[20];
int nr_mas;
double convf(char *s){
double val=0.0,putere;
int i=0,semn;
while(isspace(s[i]))
i++;
semn=(s[i]=='-')?-1:1;
if(s[i]=='+'||s[i]=='-')
i++;
for(val=0.0;isdigit(s[i]);i++)
val=10*val+s[i]-'0';
if(s[i]=='.'){
i++;
for(putere=1.0;isdigit(s[i]);i++){
val=10*val+s[i]-'0';
putere*=10;
}
val/=putere;
} /*sfirsit parte zecimala*/
val*=semn;
if(s[i]=='e' || s[i]=='E'){
i++;
semn=(s[i]=='-')?-1:1;
if(s[i]=='+'||s[i]=='-')
i++;
for(putere=0.0;isdigit(s[i]);i++)
putere=10*putere+s[i]-'0';
val*=pow10(semn*putere);
} /*sfirsit parte exponentiala*/
return val;
}
void loadmat(FILE *fp,int *nrm,double *mas){
int i=0;
fscanf(fp,"%d",nrm);
if (*nrm>MAX) *nrm=MAX;
for(;i<*nrm;i++)
fscanf(fp,"%lf",&mas[i]);
}
void afiseaza(double *mas,int nrm){
int i;
for(i=0;i<nrm;i++)
printf("masuratoarea %d = %6.2e\n",i+1,mas[i]);
}
void main(){
printf("nume fisier:");
gets(nume_fis);
if((fp=fopen(nume_fis,"r+"))==0){
printf("nu exista fisierul\n");
exit(1);
}
loadmat(fp,&nr_mas,masur);
afiseaza(masur,nr_mas);
fseek(fp,0L,SEEK_END);
printf("\nmasuratoarea %d =",++nr_mas);
while((mas_noua=convf(gets(s))) && nr_mas<MAX-1){
printf("\nmasuratoarea %d =",++nr_mas);
fprintf(fp,"%lf\n",mas_noua);
}
fseek(fp,0L,SEEK_SET);
fprintf(fp,"%3d",--nr_mas);
fclose(fp);
}