Documente Academic
Documente Profesional
Documente Cultură
Limbajul C
CURS 10
Fiiere
Fiier
Colecie de date memorate pe un suport extern (floppy, harddisk, etc) identificat printr-un nume. Entiti ale sistemului de operare: numele lor respect conveniile sistemului, fr legtur cu un limbaj de programare anume Coninutul:
texte (ex. programe surs) numere alte informaii binare: programe executabile, numere n format binar, imagini sau sunete codificate numeric s.a.
Numrul de elemente ale unui fiier este variabil (poate fi nul). Se folosesc pentru
date iniiale sau rezultate mai numeroase pstrarea permanent a unor date de interes pentru anumite aplicaii
Programarea calculatoarelor
Operarea cu fiiere
De obicei "fiier" = fiier disc (pe suport magnetic sau optic) Noiunea de fiier este mai general i include orice flux de date (stream) din exterior spre memorie sau dinspre memoria intern spre exterior. Stream (flux de date, canal) sinonim cu file (fiier): pune accent pe aspectul dinamic al transferului de date Programatorul se refer la un fiier printr-o variabil; tipul acestei variabile depinde de limbajul folosit i chiar de funciile utilizate (n C). Asocierea dintre numele extern (un ir de caractere) i variabila din program se face la deschiderea unui fiier, printr-o funcie standard.
Programarea calculatoarelor
Tipuri de fiiere n C
Fiiere text
conin o succesiune de linii, separate prin NewLine fiecare linie are 0 sau mai multe caractere tipribile i/sau tab
Fiiere binare
conin o succesiune de octei
Programarea calculatoarelor
Fiiere text
Caracter terminator de linie: fiierele Unix/Linux: un singur caracter terminator de linie \n fiierele Windows i MS-DOS: caracterele \r i \n (CR,LF) ca terminator de linie Un fiier text poate fi terminat printr-un caracter terminator de fiier (Ctrl-Z = EOF = -1) nu este obligatoriu acest terminator Sfritul unui fiier disc poate fi detectat i pe baza lungimii fiierului (numr de octei), memorat pe disc. Se realizeaz conversia automat din/n format extern (ir de caractere) n/din format intern (binar virgul fix sau virgul mobil)
Programarea calculatoarelor
Fiiere binare
Pot conine
numere n reprezentare intern (binar) articole (structuri de date) fiiere cu imagini grafice, n diverse formate, etc
Citirea i scrierea se fac fr conversie de format. Pentru fiecare tip de fiier binar este necesar un program care s cunoasc i s interpreteze corect datele din fiier (structura articolelor). Este posibil ca un fiier binar s conin numai caractere, dar funciile de citire i de scriere pentru aceste fiiere nu cunosc noiunea de linie; ele specific un numr de octei care se citesc sau se scriu la un apel al funciei fread sau fwrite.
Programarea calculatoarelor
Operarea cu fiiere
1. se definete o variabil de tip FILE * pentru accesarea fiierului; FILE * un tip structur definit n stdio.h conine informaii referitoare la fiier i la tamponul de transfer de date ntre memoria central i fiier (adresa, lungimea tamponului, modul de utilizare a fiierului, indicator de sfrit, de poziie n fiier) 2. se deschide fiierul pentru un anumit mod de acces, folosind funcia de biblioteca fopen, care realizeaz i asocierea ntre variabila fiier i numele extern al fiierului 3. se prelucreaz fiierul - citire/scriere cu funciile specifice 4. se nchide fiierul folosind funcia de biblioteca fclose.
Programarea calculatoarelor
Sistemele MS-DOS i MS-Windows nu fac deosebire ntre litere mari i litere mici, n cadrul numelor de fiiere Atenie! pentru separarea numelor de cataloage dintr-o cale se vor folosi:
"\\", pentru a nu se considera o secven de caractere "Escape" sau caracterul /. char *numef = "C:\\WORK\\T.TXT"; char *numef = c:/work/t.txt;
Programarea calculatoarelor
Atenie!
nchiderea unui fiier disc este absolut necesar pentru fiierele n care s-a scris ceva! Poate lipsi dac s-au fcut doar citiri din fiier!
Programarea calculatoarelor
Exemplu
#include <stdio.h> int main ( ) { FILE * f; // pentru referire la fiier // deschide un fiier text ptr citire f = fopen ( c:\\t.txt", "rt ); printf ( f == NULL ? "Fiier negasit" : " Fiier gasit"); if (f) // dac fiier existent fclose(f); // nchide fiier return 0; }
Programarea calculatoarelor
Exemplu: scriere sub form de litere mici caracterele dintr-un fiier n alt fiier
#include<stdio.h> #include<ctype.h> #include<stdlib.h> int main () { FILE * f1, * f2; int ch; f1= fopen ("c:\\1cc\\in.txt", "r"); f2= fopen ("c:\\1cc\\out.txt", "w"); if ( f1==0 || f2==0) { puts (" Eroare la deschidere fiiere \n"); system("pause"); return 1; } while ( (ch=fgetc(f1)) != EOF) // citeste din f1 fputc ( tolower(ch),f2); // scrie n f2 fclose(f1); fclose(f2); system("pause"); return 0; }
Programarea calculatoarelor
Programarea calculatoarelor
Exemplu
ntr-un fiier de tip text sunt pstrate valorile reale ale unei msuratori sub forma: nr_msuratori '\n' val1 '\n' val2 '\n' val3 ... S se scrie programul care afieaz numrul de msurtori i valorile respective, dup care adaug la fiier noi msuratori pn la introducerea valorii 0. Valorile citite se afieaza n format tiinific.
Programarea calculatoarelor
Rezolvare
# include <math.h> # include <stdio.h> # include <stdlib.h> # include <ctype.h> # define MAX 100 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;
Programarea calculatoarelor
Rezolvare
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; 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]); }
Programarea calculatoarelor
Rezolvare
void afiseaza(double *mas,int nrm){ int i; for (i=0; i<nrm; i++) printf ("Masuratoarea %d = %6.2e\n", i+1, mas[i]); } int main(){ FILE *fp; double masur[MAX], mas_noua; char nume_fis[12], s[20]; int nr_mas; printf ("nume fisier:"); gets (nume_fis); if ( (fp = fopen(nume_fis, "r+") ) == 0 ){ printf ("nu exista fisierul\n"); exit (1); }
Programarea calculatoarelor
Rezolvare
loadmat (fp,&nr_mas,masur); afiseaza (masur,nr_mas); fseek (fp, 0L, SEEK_END); // pozitionare la sfarsit 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); // pozitionare la inceput fprintf (fp, "%d", --nr_mas); fclose (fp); system ("pause"); return 0; }
Programarea calculatoarelor
Exerciii
Program pentru numrarea liniilor i cuvintelor dintrun fiier text. Cuvintele sunt iruri de orice caractere separate ntre ele prin (oricte) spaii albe. Se va folosi funcia de biblioteca "strtok". Exemplu strtok: char *p, *sep= ="\t \r\n" ; while ( (p= strtok (p,sep)) != NULL) { p=p+strlen(p)+1; }
Programarea calculatoarelor
Funciile de acces pentru fiiere binare "fread" i "fwrite" pot citi sau scrie unul sau mai multe articole, la fiecare apelare. Transferul ntre memorie i suportul extern se face fr conversie sau editare (adugare de caractere la scriere sau eliminare de caractere la citire).
Programarea calculatoarelor
Programarea calculatoarelor
assert
void assert (int expr); Permite ca informaii de diagnostic s fie scrise la fiierul standard de eroare. Dac expr este 0 (fals), atunci expresia expr, numele fiierului i linia n care a aprut sunt trimise la fiierul standard de eroare dup care execuia programului este oprit: Assertion failed: expr, file filename, line line-number Exemplu:
#include<assert.h> void open_record(char *record_name) { assert ( record_name != NULL ); /* Rest of code */ } int main(void) { open_record(NULL); }
Programarea calculatoarelor
Exemplu
// afisare coninut fiier pe ecran void listare (char* numef) { FILE * f; Elev e; f = fopen (numef, "rb"); assert (f != NULL); printf ("Nume i medie: \n"); while ( fread (&e, sizeof(e), 1, f ) ==1 ) printf ("%-25s %6.2f \n", e.nume, e.medie); fclose (f); } // adaugare articole la sfritul unui fiier existent void adaugare (char * numef) { FILE * f; Elev e; f = fopen (numef, "ab"); assert (f != NULL); printf ("Adaugare nume i medie:\n"); while (scanf ("%s%f", e.nume, &e.medie) != EOF) fwrite (&e, sizeof(e), 1, f); fclose (f); }
Programarea calculatoarelor
Programarea calculatoarelor
Exemple
poziionarea la sfritul fiierului: fseek (fp, 0, SEEK_END) poziionarea la caracterul precedent: fseek (fp, -1, SEEK_CUR) poziionarea la inceputul fiierului: fseek (fp, 0, SEEK_SET)
Atenie! Poziionarea relativ la sfritul unui fiier nu este garantat nici chiar pentru fiiere binare, astfel c ar trebui evitat! Ar trebui evitat i poziionarea fa de poziia curent cu o valoare negativ, care nu funcioneaz n toate implementrile!
Programarea calculatoarelor
Funcie care modific coninutul mai multor articole din fiierul de elevi creat anterior
// modificare coninut articole, dupa cautarea lor void modificare (char * numef) { FILE * f; Elev e; char nume[25]; long pos; int ef; f = fopen(numef,"rb+"); assert (f != NULL); do { printf ("Nume cautat: "); scanf ("%s",nume); if (strcmp(nume, .) == 0) break; // datele se termin cu un punct // cauta "nume" n fiier fseek (f, 0, 0); // readucere pe inceput de fiier while ( (ef=fread (&e, sizeof(e), 1, f)) ==1 ) if (strcmp (e.nume, nume)==0) { pos= ftell(f) - sizeof(e); break; }
Programarea calculatoarelor
Exemplu
if ( ef < 1) break; printf ("noua medie: "); scanf ("%f", &e.medie); fseek (f, pos, 0); // pe inceput de articol gasit fwrite (&e, sizeof(e), 1, f); // rescrie articol modificat } while (1); fclose (f); } int main(){ char name[]="c:elev.txt; creare (name); listare (name); adaugare (name); modificare (name); listare (name); system("pause"); return 0; }
Programarea calculatoarelor
Fiiere predefinite
Exist trei fluxuri predefinite, care se deschid automat la lansarea unui program: stdin - fiier de intrare, text, este intrarea standard - tastatura stdout - fiier de ieire, text, este ieirea standard - ecranul monitorului. stderr - fiier de iesire, text, este ieirea standard de erori - ecranul monitorului. pot fi folosite n diferite funcii practic se folosesc n funcia "fflush" care golete zona tampon ("buffer") asociat unui fiier.
Programarea calculatoarelor
Programarea calculatoarelor
Observaii
Nu orice apel al unei funcii de citire sau de scriere are ca efect imediat un transfer de date ntre exterior i variabilele din program! Citirea efectiv de pe suportul extern se face ntr-o zon tampon asociat fiierului, iar numrul de octei care se citesc depind de suport: o linie de la tastatur, unul sau cteva sectoare disc dintr-un fiier disc, etc. Cele mai multe apeluri de funcii de I/E au ca efect un transfer ntre zona tampon (anonim) i variabilele din program. Funcia fflush are rolul de a goli zona tampon folosit de funciile de I/E, zon altfel inaccesibil programatorului C. Are ca argument variabila pointer asociat unui fiier la deschidere, sau variabilele predefinite stdin i stdout.
Programarea calculatoarelor