PC Laborator 13

De la WikiLabs

Obiective

La încheierea acestui laborator studentul va fi capabil să:

  • să lucreze cu fișiere text: deschidere, citire, scriere, închidere
  • să înțeleagă modul de funcționare al fișierelor binare

Informații generale

Datele pot fi stocate temporar în memoria internă, dar la închiderea programului acestea se vor pierde. Pentru suportul acestui dezavantaj se poate folosi noțiunea de fișier, desigur stocat in memoria externă. Memoria externă furnizează o capacitate de stocare mult mai mare decât memoria internă, nu este volatilă, deci nu-şi pierde conţinutul la o eventuală întrerupere, dar are ca principal dezavantaj viteza de transfer a datelor redusă.

Prelucrarea unui fişier presupune asocierea acestuia cu un canal de I/E (numit flux sau stream).(vezi PC Laborator 3).

Limbajul C permite operarea cu fişiere:

  • text - fişier ce conţine o succesiune de linii
  • binare - fişier conţine o succesiune de octeti, fără o structură.
  • "b" - specifică fişier de tip binar
  • "t" - specifică fişier de tip text (implicit)

Operații cu fișiere

Pentru a avea acces la informaţiile dintr-un fişier, se realizează următoarele operaţii:

  • deschiderea fişierului
  • citirea/scrierea conţinutului fişierului
  • închiderea fisierului
Observatie: Operaţiile cu fişierele se realizează prin intermediul unui set de funcţii din biblioteca standard de intrare/ieşire (I/O), deci este necasară includerea fişierului header stdio.h.

Atunci când intenționăm să lucrăm cu fişiere este necesar să ne definim un pointer către o structură de tipul FILE. O structură de tipul FILE este o structură de control a streamurilor. Această structură păstrează informaţii cum ar fi adresa de început, poziţia indicatorului de fişier, poziţia indicatorului de sfârşit a fişierului și altele. Pentru a se putea utiliza un fişier, este necesară folosirea unui pointer. Acesta este un pointer către anumite informaţii despre fişierul respectiv – nume, starea şi poziţia în care se află poinetrul de fişier.

FILE * fisier;

Deschiderea fișierelor

Fişierele necesită a fi inițializate, le trebuie asociat un fişier fizic de pe dispozitivul de stocare.

FILE *fopen(const char *nume_fișier, const char *mod);
FILE -returnează un pointer la fișier
nume_fișiere -se specifică numele sau calea acestuia
mod -se specifică modul de deschidere al fișierului

Moduri de deschidere al fișierelor:

  • "r" - (read only), permite deschiderea doar pentru citirea conținutului
  • "w" - (write), crează un nou fişier în care se pot scrie date. Dacă exista deja un fișier cu acest nume, conținutul va fi sters
  • "a" - (append), deschide pentru scriere într-un fişier existent (scrierea se va face în continuare) -adăugare-
  • "r+" - deschide un fişier pentru actualizarea datelor, permite atât scriere cât şi citire
  • "w+" - crează un fişier nou în care se vor putea scrie cât şi citi date.
  • "a+" - deschide un fişier pentru adăugare de date cât şipentru citire. Operațiile de scriere vor fi efectuate în continuarea datelor existente
Observatie: Dacă operaţia de deschidere eşuează, funcţia returnează valoarea NULL. Dacă deschiderea reuşeşte, funcţia returnează o valoare de tip FILE *.

Exemplu

FILE *fisier;
fisier = fopen("exemplu.txt", "w");

if (fisier == NULL) {
    printf("Fisierul nu poate fi creat.");
} else {
    printf("Fisierul a fost creat");
}
Observatie: În acest mod se confirmă și crearea corectă a fișierului, fiind o practică recomandată.

Închiderea fișierelor

După ce sunt folosite, fişierele trebuie închise. Atunci când execuţia programului se încheie cu succes (fie prin încheierea execuţiei funcţiei main (), fie prin apelarea funcţiei exit() ), toate fişierele deschise în momenul respectiv sunt automat închise. Închiderea unui fişier se face cu funcţia fclose ().

int fclose(FILE *fisier)
Observatie: Funcţia fclose() returnează 0 dacă operaţia de închidere a fişierului s-a realizat cu succes şi EOF dacă a intervenit o eroare.

Exemplu

FILE *fisier;
fisier = fopen("/work/pc/F/group1/ion/lab13/test.txt", "w");

if (fisier == NULL) {
    printf("Fisierul nu a putut fi creat");
} else { 
    //... 
    fclose(fisier); 
}

Parcurgerea fișierelor

Orice fişier, odată deschis, are asociat un cursor care indică poziţia curentă în fişierul respectiv (inițial această poziție este la începutul fişierului). Funcţiile de scriere şi citire din fişiere operează începand de la poziţia curentă a cursorului. Totodată, orice operaţie de scriere sau citire avansează automat acest cursor cu numărul de octeţi citiţi/scrişi.

Poziția curent este dată de funcția ftell():

int ftell(FILE *fisier)

Poziţionarea cursorului pe o anumita poziţie se poate face folosind funcţia fseek():

int fseek(FILE *fisier, long pozitie, int referinta)
Observatie: În termeni uzuali se folosește long offset, int whence. Offset fiind numărul de octeți peste care se deplasează, iar whence poziția cursorului

Whence poate avea una din cele trei valori posibile:

  • SEEK_SET = 0 - Căutarea se face de la începutul fişierului
  • SEEK_CUR = 1 - Căutare din poziţia curentă
  • SEEK_END = 2 - Căutare de la sfârşitul fişierului

Citirea şi scrierea în/din fişiere

În cazul în care se lucrează cu fişiere text se folosesc în mod uzual următoarele funcţii:

  • scriere: fputs() şi fprintf()
  • citire: fgets() şi fscanf()

Funcţiile fscanf() şi fprintf() funcţionează identic cu funcţiile scanf() şi printf(), cu deosebirea că citirea respectiv scrierea operează asupra unui fişier specificat ca prim parametru:

int fprintf(FILE *f, const char *format, ...);
int fscanf(FILE *f, const char *format, ...);

Funcţiile recomandate pentru lucrul cu fişiere binare sunt urmatoarele:

  • scriere: fwrite()
  • citire: fread()
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);

Exerciții

  1. Să se scrie un program care citește de la tastatură un text de mai multe linii și îl scrie într-un fișier text.
  2. Să se scrie un program care citește un fișier text și îl afișeză linie cu linie.