Home - Rasfoiesc.com
Educatie Sanatate Inginerie Business Familie Hobby Legal
Doar rabdarea si perseverenta in invatare aduce rezultate bune.stiinta, numere naturale, teoreme, multimi, calcule, ecuatii, sisteme




Biologie Chimie Didactica Fizica Geografie Informatica
Istorie Literatura Matematica Psihologie

Informatica


Index » educatie » Informatica
» Lucrul cu fisiere


Lucrul cu fisiere


Obiectivul laboratorului este urmatorul:

  1. Prezentarea lucrului cu fisiere (text si binare)

introducere in lucrul cu fisiere;

functii folosite in lucrul cu fisiere;

implementarea unei stive



1. Introducere in lucrul cu fisiere

Un fisier reprezinta o secventa de date stocata in memoria externa a unui calculator (pe harddisk-uri, dischete, CDROM, etc). Dupa cum se stie, memoriile externe dispun de capacitati de stocare mult mai mari decat memoria interna, nu sunt volatile (nu-si pierd continutul la intreruperea alimentarii cu energie electrica), dar au ca principal dezavantaj viteza de transfer a datelor mult mai redusa decat memoria interna. De asemenea, memoriile externe nu dispun de conexiune directa cu procesorul calculatorului.

Asadar, pentru a se putea prelucra informatiile din fisiere, programele trebuie sa aduca informatiile din fisiere in memoria interna (RAM) si apoi in variabilele programului, pentru efectuarea prelucrarilor necesare asupra informatiilor respective, iar apoi sa transfere rezultatele inapoi in fisiere.

In limbajul C, operatiile cu fisierele se realizeaza prin intermediul unui set de functii din biblioteca standard de intrare/iesire (I/O), care necesita includerea fisierului header stdio.h.

Pentru a se putea accesa informatiile dintr-un fisier, trebuie efectuate urmatoarele operatii:

- deschiderea fisierului;

- citirea/scrierea continutului fisierului;

- inchiderea fisierului;

Deschiderea fisierului este necesara datorita faptului ca sistemul de operare trebuie sa aloce resurse interne, pentru a se putea accesa continutul fisierului. Aceste resurse sunt eliberate in momentul inchiderii fisierului respectiv.

In momentul deschiderii unui fisier, programatorul trebuie sa indice sistemului de operare trei elemente:

numele fisierului;

modul de accesare al fisierului (citire, scriere, adaugare la sfarsit, actualizare - citire si scriere);

tipul fisierului: text sau binar;

Referitor la tipul fisierului, trebuie facuta distinctia intre fisierele binare si fisierele text, atunci cand programatorul doreste sa acceseze (si sa modifice) continutul unui fisier. Diferentele apar la nivelul functiilor de biblioteca pentru citirea si scrierea continutului fisierelor.

Un fisier binar se acceseaza ca o succesiune (un flux) de octeti, carora functiile de citire si scriere din fisier nu le dau nici o interpretare.

Un fisier text se acceseaza ca o succesiune de linii de text de lungime variabila, utilizand un set dedicat de functii din biblioteca standard. Aceste functii inspecteaza toate caracterele citite din fisier si incheie o operatie de citire in momentul in care a fost preluat un caracter 'n' - new line (linie noua).

2. Functii folosite in lucrul cu fisiere

In limbajul C exista o serie de functii specializate in lucrul cu fisiere. Pentru a se putea folosi aceste functii, este necesara includerea fisierului header stdio.h

Principalele functii folosite in lucrul cu fisiere sunt urmatoarele:

Nume functie

Descriere functie

fopen ()

deschide un fisier

fclose ()

inchide un fisier

fputch ()

scrie un caracter intr-un fisier

fgetch ()

citeste un caracter dintr-un fisier

fseek ()

cauta un anumit octet intr-un fisier

fprintf ()

echivalentul lui printf (), folosit pentru un fisier

fscanf ()

echivalentul lui scanf (), folosit pentru un fisier

feof ()

returneaza o valoare dif. de 0 daca se ajunge la sfarsitul fisierului

ferror ()

returneaza o valoare dif. de 0 daca apare o eroare

ftell ()

returneaza pozitia cursorului intr-un fisier

Pentru a se putea utiliza un fisier, este necesara folosirea unui pointer, care sa faca legatura intre fisierul respectiv si sistemul I/O din C. Pointer-ul respectiv este un pointer catre anumite informatii despre fisierul respectiv - nume, starea si pozitia curenta a fisierului, dimensiune etc.

Deschiderea unui fisier se face cu functia fopen (), care are urmatorul prototip:

FILE *fopen (char *nume_fisier, char *mod)

Primul parametru (filename) reprezinta numele fisierului care urmeaza sa se dechida.

Al doilea parametru (mod) este un sir de caractere care indica modul de accesare si tipul fisierului. Valorile posibile pentru acest parametru sunt urmatoarele:

Valoarea lui

mod

Tipul

fisierului

Modul de accesare

'rt'

text

doar citire; daca fisierul nu exista se semnaleaza eroare

'rb'

binar

'wt'

text

doar scriere; daca fisierul nu exista, va fi creat, iar daca exista, va fi suprascris

'wb'

binar

'at'

text

doar scriere; daca fisierul nu exista va fi creat, iar daca exista se va adauga la sfarsitul lui

'ab'

binar

'r+t'

text

citire si scriere; daca fisierul nu exista se semnaleaza eroare

'r+b'

binar

'w+t'

text

citire si scriere; daca fisierul nu exista va fi creat, iar daca fisierul exista va fi suprascris

'w+b'

binar

'a+t'

text

citire si scriere; daca fisierul nu exista va fi creat, iar daca fisierul exista se va adauga la sfarsitul sau

'a+b'

binar

Daca operatia de deschidere esueaza, functia returneaza valoarea NULL. Daca deschiderea reuseste, functia returneaza o valoare de tip FILE *, care se foloseste in toate operatiile ulterioare asupra fisierului respectiv.

Exemplu: crearea (deschiderea) unui fisier si setarea atributului "w" (pentru a se putea scrie in fisierul respectiv)

FILE *fisier;

fisier = fopen ("exemplu.txt", "wt");

O versiune mai corecta a exemplului anterior este:

FILE *fisier;

fisier = fopen ("exemplu.txt", "wt");

if (fisier == NULL)

else

Aceasta varianta este recomandata, deoarece utilizatorului i se confirma crearea fisierului dorit, iar in caz contrar (protectie la scriere, disc plin etc.) se va afisa un mesaj.

Dupa ce sunt folosite, fisierele trebuie inchise. Atunci cand executia programului se incheie cu succes (fie prin incheierea executiei functiei main (), fie prin apelarea functiei exit() ), toate fisierele deschise in momenul respectiv sunt automat inchise. Daca rularea unui program este intrerupta fortat (prin blocarea executiei sau prin rularea functiei abort() ), fisierele deschise in momentul respectiv nu sunt inchise.

Inchiderea unui fisier se face cu functia fclose (), care are urmatorul prototip:

int fclose (FILE *fisier)

Parametrul fisier trebuie sa fie valoarea returnata de functia fopen (). Apelarea functiei va avea ca rezultat si scrierea oricarei date ramasa in buffer-ul discului pe care se afla fisierul, executand de asemenea inchiderea fisierului la nivel de sistem de operare.

Functia fclose () returneaza 0 daca operatia de inchidere a fisierului s-a realizat cu succes si EOF daca a intervenit vre-o eroare.

Daca un fisier nu este inchis corespunzator pot apare diverse situatii nedorite - pierderi de date, fisiere corupte sau/si distruse, posibilitatea aparitiei de erori in programul in care se foloseste fisierul (sau fisierele) respectiv(e). De asemenea, functia fclose () distruge asocierea dintre fisierul respectiv si variabila FILE * corespunzatoare, astfel incat variabila respectiva poate fi reutilizata.

Informatiile dintr-un fisier sunt accesate secvential, iterativ. Orice fisier, odata deschis, are asociat un cursor care indica pozitia curenta in fisierul respectiv (initial - inceputul fisierului respectiv). Functiile de scriere si citire din fisiere opereaza incepand de la pozitia curenta a cursorului respectivului fisier. Totodata, orice operatie de scriere sau citire avanseaza automat acest cursor cu numarul de octeti cititi/scrisi. Spre exemplu, daca pozitia curenta este pe octetul 7, scrierea sau citirea a 5 octeti avanseaza cursorul pe octetul 12.

Pozitia curenta a cursorului dintr-un fisier se poate afla folosind functia ftell ():

long ftell (FILE *fisier)

Functia ftell () returneaza pozitia (in octeti) fata de inceputul fisierului in care se afla cursorul de parcurgere a fisierului.

Pozitionarea cursorului pe o anumita pozitie din fisier se poate face, de asemenea, folosind functia fseek ():

int fseek (FILE *fisier, long pozitie, int referinta)

Parametrul fisier trebuie sa fie o valoare returnata de functia fopen (). Parametrul pozitie indica deplasarea in octeti fata de referinta unde se va pozitiona cursorul. Ca referinta (al treilea parametru), se pot folosi urmatoarele valori:

SEEK_SET - fata de inceputul fisierului;

SEEK_CUR - fata de pozitia curenta a cursorului respectivului fisier

SEEK_END - fata de sfarsitul fisierului

Observatie: functia fseek () nu se apeleaza de obicei cand se lucreaza cu fisiere text, deoarece acestea sunt formate din linii de lungime variabila, astfel incat avansarea cu un anumit numar de octeti nu ofera nici o garantie asupra faptului ca la noua pozitie este chiar inceputul unei linii.

Exemplu: program care determina si afiseaza dimensiunea in octeti a unui fisier:

#include <stdio.h>

long get_file_size (FILE *fisier)

void main (void)

else

Daca se lucreaza cu fisiere text se folosesc urmatoarele functii:

pentru scriere: sunt folosite functiile fputs () si fprintf ();

pentru citire: sunt folosite functiile fgets () si fscanf ();

Daca se lucreaza cu fisiere binare se folosesc urmatoarele functii:

pentru scriere: se foloseste functia fwrite ()

pentru citire: se foloseste functia fread ();

Observatie: atunci cand cursorul ajunge la sfarsitul fisierului, scrierea in fisierul respectiv are ca efect cresterea dimensiunii fisierului cu numarul de octeti scrisi.

Functiile fputs () si fgets ()

Functiile fputs () si fgets () sunt folosite pentru citirea si scrierea de siruri de caractere in sau dintr-un fisier text.

Prototipurile acestor functii sunt urmatoarele:

int fputs (char *sir, FILE *fisier);

char *fgets (char *sir, int lungime, FILE *fisier);

Functia fputs () scrie in fisierul specificat sirul spre care indica pointer-ul sir. Daca apare vreo eroare, functia fputs () returneaza EOF.

Functia fgets () citeste un sir de caractere din fisierul specificat, pana cand este intalnit un caracter de linie noua sau atunci cand au fost citite lungime-1 caractere. Daca este citit un caracter de linie noua, acesta va fi inclus in sir. Functia va returna sirul de caractere sir daca citirea s-a facut corect si returneaza valoarea NULL daca apare o eroare in timpul citirii. Sirul rezultat (in urma citirii) se termina cu '0'.

Functiile fscanf () si fprintf () functioneaza identic cu functiile scanf () si printf (), cu deosebirea ca citirea respectiv scrierea se face opereaza asupra unui fisier specificat ca prim parametru, permitand folosirea sirurilor si a caracterelor de formatare.

int fscanf (FILE *f, char *format, adresele variabilelor);

int fprintf (FILE *f, char *format, valorile variabilelor);

Functiile fread () si fwrite ()

Functiile fread () si fwrite () sunt folosite pentru scrierea datelor in fisierele binare, fara a da nici o interpretare continutului. Astfel, functiile fread () si fwrite () sunt folosite pentru citirea si scrierea de blocuri de date structurate, fisierul rezultat fiind o copie a continutului blocului de memorie din care se face scrierea in fisier (in cazul fwrite () ) sau o imagine a continutului fisierului (in cazul fread ()).

Prototipurile functiilor fread () si fwrite () sunt urmatoarele:

size_t fread (void *ptr, size_t noct, size_t nr, FILE *f);

size_t fwrite (void *ptr, size_t noct, size_t nr, FILE *f);

In cazul functiei fread (), pointer-ul ptr este un pointer catre o regiune de memorie care va primi datele din fisierul respectiv, iar in cazul functiei fwrite () pointer-ul ptr este un pointer catre informatiile care vor fi scrise in fisierul respectiv.

Valoarea nr specifica numarul de elemente citite sau scrise, fiecare dintre elementele respectiver avand dimensiunea in octeti specificata in parametrul noct.

Functia fwrite () returneaza numarul de elemente scrise in fisier, daca nu apare nici o eroare in timpul scrierii (valoarea returnata va fi egala cu nr daca nu intervine nici o eroare).

Functia fread () returneaza numarul de elemente citite, putand fi mai mica decat valoarea lui nr, daca se ajunge la sfarsitul fisierului sau daca apare vreo eroare.

Exemplu de folosire a functiei fwrite ():

#include <stdio.h>

#include <string.h>

typedef struct

student;

void main(void)

Exemplu de folosire a functiei fread () (pentru fisierul creat in exemplul anterior):

#include <stdio.h>

typedef struct

student;

void main(void)

Exemple rezolvate

Exemplul 1: program care citeste un fisier text si il afiseaza linie cu linie:

#include <stdio.h>

#include <stdlib.h>

void main (void)

fclose (fis);

free (sir);    // eliberarea memoriei alocate

Exemplul 2: program care citeste de la tastatura un text de mai multe linii si il scrie intr-un fisier text:

#include <stdio.h>

#include <stdlib.h>

void cit_sir (char *sir)

while (strlen (sir) == 0);

void main (void)

fclose (fis);

Exemplul 3: program care citeste de la tastatura cateva inregistrari de tip structura (ex. informatii despre studenti - numele si varsta) si le scrie intr-un fisier:

#include <stdio.h>

#include <string.h>

#define DIM 100

typedef struct

student;

student tab[DIM];

int n;

void cit_sir (char *sir)

while (strlen (sir) == 0);

void main (void)

// se creeaza un fisier binar

f = fopen ('ex_binar.bin', 'wb');

if (f == NULL)

printf ('Fisierul nu se poate crea!');

else

Exemplul 4: program care citeste fisierul generat de exemplul anterior si afiseaza inregistrarile citite:

#include <stdio.h>

#define DIM 100

typedef struct

student;

student tab[DIM];

int n;

void main (void)

fclose (f);

3. Stiva.

Se propune realizarea unui program C care sa implementeze o stiva utilizand alocarea dinamica. Elementele stivei sunt reprezentate de adrese (nume strada si numar). Exemplul urmator ilustreaza programul care implementeaza adaugarea elementelor in stiva si listarea continutului stivei.

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <stdlib.h>

typedef struct

adresa;

void main(void)

while(c!=NULL);

break;

} while(opt!=3);

getch();

Probleme propuse

Sa se realizeze un program care copiaza dintr-un fisier text intr-un alt fisier text doar liniile care contin un anumit cuvant, introdus de la tastatura.

Sa se realizeze un program care sterge un anumit student (al carui nume este introdus de la tastatura) din baza de date creata cu penultimul exemplu rezolvat (Exemplul 3).

Indicatie: nu exista nici o modalitate de a micsora dimensiunea unui fisier. Singura posibilitate de a elimina o inregistrare dintr-un fisier este de a genera un alt fisier care sa contina toate inregistrarile din cel initial, mai putin cea care trebuie stearsa. Apoi se poate utiliza functia remove pentru a sterge fisierul initial si rename pentru a redenumi fisierul generat la numele initial:

int remove (char *filename);

int rename (char *old_name, char *new_name)

La functia remove, parametrul filename reprezinta numele fisierului care se va sterge.

La functia rename, parametrul old_name si new_name reprezinta numele initial respectiv cel final al fisierului).

In momentul aplicarii functiilor, fisierele respective trebuie sa fie inchise, alfel functiile esueaza! Functiile returneaza valoarea 0 daca operatia a reusit sau o valoare diferita de 0 in caz de esec.

Sa se realizeze un program care continua implementarea stivei realizate in cadrul ultimului paragraf. Implementarile ulterioare trebuie sa permita cautarea unei adrese in stiva (dupa numele strazii) si stergerea unei adrese din stiva.





Politica de confidentialitate





Copyright © 2024 - Toate drepturile rezervate