Documente Academic
Documente Profesional
Documente Cultură
FCIM
Catedra Calculatoare
RAPORT
la lucrarea de laborator nr. 3
la Structuri de date si algoritmi
Tema: : Elaborarea programelor pentru prelucrarea funciilor cu diverse
structuri i fiiere n limbajul C.
A efectuat:
A verificat:
Marin tefan
Chiinu 2015
Sarcina i obiectivele:
-s se analizeze principiile organizrii i gestiunii fiierelor n sistemele de operare i procesarea fiierelor
n limbajul C, apoi i s se analizeze algoritmii i programele (declarri, utilizri, parcurgeri, salvare i
tergeri).
-de studiat i nsuit materialul teoretic prin lansarea exerciiilor de antrenament i verificri ale
cunotinelor (din indicaiile acestea) i s se elaboreze algoritmii i, totodat, s organizeze calculele de
verificare cu explicaii pentru evidenierea esenialului prelucrrii fiierelor cu structuri de date n
elaborarea modelelor soluiei. Toate observaiile se nregistreaz n raport;
-s se preia de la profesor varianta (4,5. Variante pentru lucrul individual) i s se elaboreze algoritmii i i
programul unde s organizeze antetul functiilor i transmiterea functiei apelate adresele variabilelor cu
calculele de verificare i cu explicaii la prelucrarea fiierelor. Pentru aprofundarea i rularea programelor
n limbajul C s se elaboreze scenariile succinte de soluionare cu calculele de verificare i explicaii.
-n baza funciilor de timp i dat din fiierul header time.h apreciai timpul definit de sistem i timpul
execuiei programului n secunde pentru ambele cazuri (tradiional i cu pointeri) i s se descrie scenariile
i principiile de algoritmizare si rezolvare ale problemei n baza diferitor modele de SD complexe,
implementnd subprograme n C;
-n raport s se reflecte toate exemplele efectuate cu analize a tehnicii programrii eficiente cu argumentri
i comentarii, incluznd fiierele cu teste de verificare i vizualizri ale rezultatelor.
Pointer
FILE
Program
Scierea
Citirea
tampon
Deschiderea fisierelor
nainte ca un program s poat manipula un fiier , el trebuie s nceap prin a-l deschide.
Deschiderea unui fiier pentru programul dat const prin a deschide un acces cu ajutorul
sistemului de exploatare :n caz de reuit el va aciona aranjnd ntr-o structur FILE n vederea
operaiilor ulterioare asupra fiierului . Toate aceste aciuni sunt efectuate prin funcia predefinit
fopen.
Iat prototipul funciei:
FILE *fopen (char * nume_fiier ,char* mod_ acces )
Fopen returneaz efectiv pointerul spre tipul FILE .Acest pointer o ntoarce spre structur n
care funcia aranjeaz informaiile coninute n fiierul deschis. Parametrul nume_fiier este un
pointer spre irul de caractere ce conine numele fiierului coninut. Parametrul mod_acces este
un pointer spre irul de caractere , care indic natura operaiilor pe care programul va trebui s-l
execute dup deschiderea fiierului. S presupunem c se dorete s se deschid un fiier .
Trebuie de nceput prin definirea pointerului FILE: FILE */ definete un pointer FILE */
Pentru a efectua operaia propriu-zis:
Fp=fopen (xyz,dat, r): /* deschide fiierul */
Dac ea reuete , adresa structurii FILE coninnd informaiile relative fiierului este afectat
de pointerul Fp
Dac fiierul nu-l va gsi n repertoriul indicat , funcia fopen se fondeaz pe modelul r . El
returneaz atunci valoarea NULL .
/* open xyz ncearc fiierul xzy.dat */
#include <stdio.h > /* pentru FILE , open , printf */
main () {
FILE fp ; / definete pointerul fiierului */
if (( fp=fopen (xyz.dat, a))==NULL /* ncearc s deschid fiierul */
printf ( eroare : imposibil de deschis fiierul /XYZ:dat /./n);
printf ( fiier / xyz.dat / deschide .n);
n acest exemplu de program funcia fopen nu rentoarce pointerul nul dac fiierul nu exist.
Din contra, fiierul este creat n acest caz n repertoriul curent. Funcia fopen returneaz NULL
dac fiierul nu poate fi deschis printr-o alt cale.
Stocarea sub form binar are ca avantaje faptul c datele ocup n medie (nu mereu)
mai puin memorie dect cele n format text, au structur previzibil, dar cel mai important, pot
fi ncrcate direct n memorie. (Exemplu: un binar executabil, care este de fapt imaginea din
care este lansat un proces n execuie). Dezavantajul const n faptul c ele devin complet
neinteligibile pentru oameni (trebuie s le interpretm cu o alt aplicaie pentru a le nelege).
n acest caz, datele se reprezint pe un numr cunoscut de Bytes (mai exact, dimensiunea
tipului de dat). Dup cum se vede din exemplu, asta nu nseamn mereu c se ocup mai puin
memorie. Cu toate acestea, n mod statistic, datele binare ocup mai puin memorie!
O problem este c dac am vrea s deschidem fiierul pentru a citi aceste date, nu s-ar
nelege mai nimic, pentru c orice editor ar ncerca s transforme fiecare Byte ntr-un caracter pe
care s l afieze pe ecran. Evident, nu se obine ceea ce ne-am dori noi sa vedem. Avem nevoie
de un program care s interpreteze fiierul i s ne arate coninutul din el.
Din nou, cel mai important este c dac am vrea s citim aceste date din fiier, le putem
ncrca direct la adresa unei structuri de tip Elev. n realitate, aceste date nu sunt cu nimic mai
mult dect o "fotografie" a unei poriuni din RAM, astfel nct citirea este de fapt o simpl
copiere.
Funcii de citire i scriere la nivel de octet:
Primul lucru pe care trebuie s l facem pentru a putea folosi un fiier este s l deschidem. n
acest sens, lucrurile stau foarte simplu: trebuie doar s adaugm "b" la irul care specific modul
de deschidere al unui fiier n funcia fopen().
Cteva exemple:
Semnifica Fiiere
Fiiere
ie
binare
text
citire
"rb"
"r"
scriere
"wb"
"w"
adugare
"ab"
"a"
Pentru citire la nivel de octet se folosete funcia fread() definit n headerul <stdio.h>, care
are urmtoarea sintax:
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );
Semnificaia argumentelor este urmtoarea:
void* ptr este un pointer ctre o zon de memorie unde se va face citirea
size_t size reprezint dimensiunea n octei a unui element citit
size_t count reprezint numrul de elemente citite. Elementele vor fi depuse n locaii
consecutive ncepnd de la adresa ptr din memorie
FILE* stream reprezint fluxul (fiierul) din care se face citirea
Pentru scriere la nivel de octet se folosete funcia fwrite() definit n headerul <stdio.h>,
care are urmtoarea sintax:
size_t fwrite ( void * ptr, size_t size, size_t count, FILE * stream );
Semnificaia argumentelor este urmtoarea:
void* ptr este un pointer ctre o zon de memorie unde se vor prelua datele ce trebuie scrise
size_t size reprezint dimensiunea n octei a unui element scris
size_t count reprezint numrul de elemente scrise. Elementele vor fi preluate pentru scriere
din locaii consecutive ncepnd de la adresa ptr din memorie
FILE* stream reprezint fluxul (fiierul) n care se face scrierea
Nu n ultimul rnd, fiierele binare au o proprietate interesant: Am spus c spaiul ocupat de
diverse articole depinde exclusiv de tipul lor de dat. Cu alte cuvinte, dac am vrea s citim al
101-lea numr ntreg dintr-un fiier binar care conine doar numere ntregi, tim sigur c acest
numr ocup Bytes-ii cu numerele 400, 401, 402 i 403 din fiier. (Presupunnd c
sizeof(int)==4. Numerele se schimb dac avem alte arhitecturi cu alte tipuri de date.)
Ar fi foarte convenabil dac am putea sri peste restul fiierului direct la acea locaie de
memorie. n realitate, acest lucru este posibil. Pentru a rezolva aceast problem, C-ul pune la
dispoziie dou funcii:
long int ftell ( FILE * fisier ), ntoarce o valoare care reprezint poziia curent n fiier.
int fseek ( FILE * fisier, long int deplasament, long int fata_de_acest_punct ), sare n fiierul
fisier la poziia obinut prin suma celor doi parametri ntregi. Deplasamentul reprezint un numr
de Bytes peste care se sare, iar punctul faa de care se sare poate fi una din constantele:
SEEK_SET, nceputul fiierului
SEEK_CUR, poziia curent n fiier (salt autorelativ)
SEEK_END, poziia final din fiier (nu adunai valori pozitive :D)
nchiderea fiierelor
Cnd un fiier nu mai servete , el se poate nchide. Legtura sa cu pointerul FILE
corespunztor este ntrerupt. Funcia nivelului nalt competent pentru a nchide un fiier este
fclose .Teoretic s-ar putea de renunat s apeleze explicit fclose n program . Fclose este chemat
automatic la sfritul programului , pentru a nchide toate fiierele nc deschise.
Funcia predefinit fclose admite prototipul:
int fclose (FILE * pointer_fiier );
Ea posed ca parametru un pointer spre tipul FILE . Fclose returneaz valoarea 0 dac a putut
s deschid fiierul ataat la pointer_fiier .
Urmtorul exemplu de program ncearc s deschid un fiier a crui nume e
trecut pe linia de comand .Dac va reui , fiierul este renchis cu ajutorul funciei fclose
/* openclose arat cum se deschide i se nchide un fiier a crui nume a dat pe linia de
comand. */
#include stdio.h /* printf , fopen , close */
Funciile fputc i fgetc permit de a scrie sau de a citi caracterele izolate n fiier.
Iat prototipul funciei fputc : int fputc (intcaracter , FILE pointer _fiier).
Ea transfer un caracter dat ca prim parametru , n fiierul reprezentat prin pointer_fiier.
Tipul caracterului este convertit de int cu unsigned char. Valoarea fputc nu este altceva dect
caracterul scris sau mai bine EOF n caz de eroare .S presupunem c este un pointer ataat la un
oarecare fiier , pointerul coninnd adresa structurii FILE aferente. Deci instrucia :
fputc(A, fp); /* scrierea unui caracter n fiier */
scrie caracterul A n fiierul ataat la fp , la poziia tratamentului curente.
Citirea cu caractere cu ajutorul funciei fgetc
Omologul funciei fputc este funcia fgetc care citete un singur caracter n fiier.
int fgetc (FILE * pointer_fiier); /* prototipul lui fgetc */
Funcia fgetc returneaz caracterul citit sub forma unei valori int. Dac valoarea trimis este
EOF , sfritul fiierului a fost atins sau are o eroare. Valoarea EOF explic de ce caracterul citit
este returnat sub forma valorii int i nu valorii char.
Programul urmtor arat o aplicare elementar cu fgetc i fputc. El scrie n fiier un text
introdus de la tastatur. Numele fiierului este introdus de utilizator .
/* scrie n fiier un text n lungime
introdus de la tastatur, apoi afieaz la cerere.
Operaiile */
/* de I/E n fiier utilizeaz funciile fgetc i fputc.
*/
# include stdio.h
/* fgetc, fputc, getchar , printf */
# include conio.h
/* getche , getch */
# include ctype.h
/* toupper */
# include stdlib.h
/* exit */
#define END 64
/* caractere @ */
main ()
FILE *fp; /* pointer spre structura FILE */
char fillename 81; /* numele fiierului */
int I , repl, rep 2; /* variabila de control */
int c ; /* caracterul tampon */
printf (nregistrarea textului. Numele fiierului */n );
do
/* fin while */
fclose (fp); /* fin if rep2==0 */
fgets()
Citete un ir de caractere n fiier.
fseek()
Schimb poziia pointerului n fiier la o nou locaie.
fprintf() nscrierea cu format n fiier.
fscanf()
Citete cu format din fiier.
feof()
ntoarce o valoare diferit de 0, dac s-a ajuns la sfritul fiierului.
fread()
Citete un articol din flux.
fwrite()
nscrie n flux un articol.
rewind() Repoziioneaz pointerul fiierului asociat fluxului la nceput de fiier.
remove() terge fiierul.
Exemple pentru functiile ce 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:
- 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
-numarul depunerilor din fiecare zi, si suma totala depusa in fiecare zi, tinand cont ca
tranzactiile dintr-o zi sunt contigue in fisier. */
#include<stdio.h>
#include<conio.h>
#include<dos.h>
#include<stdlib.h>
#define MAX 3
typedef struct {
int zi; int luna; int an; } DATA;
typedef struct { unsigned char nume[30]; DATA dat; int sum; } CLIENT;
void main() { CLIENT bd[MAX]; int j,sm,i,smax,ni; FILE *baza;
baza=fopen("date.dat","r"); fread( bd, sizeof( CLIENT ), MAX, baza ); fclose( baza );
smax=0;
for(i=0;i<MAX;i++) {
if (smax<bd[i].sum) { smax=bd[i].sum; ni=i; } }
printf("\n %s , %d-%d-%d , %d \n",bd[ni].nume, bd[ni].dat.zi, bd[ni].dat.luna, bd[ni].dat.an,
bd[ni].sum);
j=1; sm=bd[0].sum;
for (i=1;i<MAX;i++) {
if (bd[i].dat.zi==bd[i-1].dat.zi && bd[i].dat.luna==bd[i-1].dat.luna && bd[i].dat.an==bd[i1].dat.an)
{ j=j+1; sm=sm+bd[i].sum; } else {
printf(" \n Nr. depuneri din data %d-%d-%d = %d ; Suma depusa = %d ",bd[i-1].dat.zi,bd[i1].dat.luna,bd[i-1].dat.an,j,sm);
j=1; sm=bd[i].sum;} }
printf(" \n Nr. depuneri din data %d-%d-%d = %d ; Suma depusa = %d ",bd[i-1].dat.zi,bd[i1].dat.luna,bd[i-1].dat.an,j,sm);
printf("\n \n"); }
4.10
De multe ori trebuie s introducem datele nu de la tastatur, dar dintr-un fiier, i nu s se
afieze rezultatul pe ecran, dar de nscris n fiier. Urmtorul exemplu prezint simplu cum
organizeaz un program lucrul cu fiiere:
/*
* Filel.c
* Acest program demonstreaz utilizarea C acestora pentru :
#include <stdio.h>
#include <conio.h>
#define MIN_DISCOUNT .97
#define MAX_DISCOUNT .95
void main()
{ float frPrice, fbPrice; FILE *fin, *fout; fin = fopen("customer.dat", "r"); fout =
fopen("billing.dat", "w");
if (fin == NULL)
{ printf("Fisierul CUSTOMER.DAT nu exista!");
getch();
return; }
while (fscanf(fin, "%f", &frPrice) != EOF)
{ if (frPrice < 100) fbPrice = frPrice * MIN_DISCOUNT;
else
fbPrice = frPrice * MAX_DISCOUNT;
fprintf(fout, "Suma $%8.2f ", frPrice); printf("Suma $%8.2f ",frPrice); fprintf(fout, "cu rabat e $
%8.2f\n", fbPrice);
printf("cu rabat e $%8.2f\n", fbPrice); } printf("\nDatele de mai sus au fost salvate");
printf(" in fisierul BILLING.DAT!"); getch();
}