Sunteți pe pagina 1din 68

CURS 11

SISTEMUL DE INTRĂRI/IEŞIRI
in limbajul C/C++
CUPRINS

1. Flux, fişier
2. Operaţii pe fişiere

2
1. FLUX, FIŞIER
 In limbajul C, sistemul I/E nu este o parte a limbajului, ci
este adăugat printr-un set de funcţii din biblioteca standard
(stdio.h, cstdio)
 Transferurile cu dispozitivele periferice (DP) se fac prin
intermediul unor dispozitive logice identice numite stream
(flux) şi prin intermediul SO:
 acest lucru permite ca detaliile funcţionale ale DP să poată fi
ignorate la nivelul programului
 Cu ajutorul fluxurilor:
 programatorul utilizează aceleaşi funcţii indiferent de DP cu
care lucrează
 sunt ascunse detaliile fizice de funcţionare ale DP
3
FLUX
 Tipuri de fluxuri :
 flux text:
 transferă secvenţe de caractere organizate în linii

 în limbajul C separarea liniilor se face prin caracterul

NewLine (LF) (0x0A)


 pentru adaptarea la dispozitiv poate fi necesară o
conversie de genul LF→ CRLF (0x0A -> 0x0D0x0A)
astfel că numărul de caractere transferate către flux
poate diferi de numărul de caractere din dispozitivul
fizic
 flux binar:
 transferă octeţi fără nici o structură şi fără alte
prelucrări
4
FLUX

 Există dispozitive logice (fluxuri) predefinite:


 se crează automat la lansarea în execuţie a unui
program şi sunt închise automat la încheierea execuţiei

 stdin: intrare standard; stream de tip text; (CON:)


 stdout: ieşire standard; stream de tip text; (CON:)
 stderr: ieşire standard erori; stream text; (CON:)

5
FLUX

 Majoritatea funcţiilor de I/E lucrează prin intermediul unui


buffer (zonă tampon):
 o zonă de memorie în care se introduc datele înainte
de a fi transferate de la/către dispozitivul periferic

 De exemplu, la intrarea datelor de la consolă, se


memorează datele de intrare în buffer până la apăsarea
tastei ENTER, după care se transferă toate datele

6
FLUX

 Fişierele conţin o înregistrare specială pentru sfârşitul de


fişier numită EOF (End Of File)
 valoarea EOF poate fi generată de la tastatură cu
combinaţia Ctrl + Z (0x1A), în general precedat şi urmat de
ENTER (optional)

 In stdio.h este definită constanta simbolică EOF:


#define EOF -1

 Prelucrarea fişierelor implică un număr de operaţii


specifice: creare, deschidere, citire, actualizare,
adăugare, poziţionare, ştergere, închidere
 o operaţie într-un fişier se face întotdeauna într-o
anumită poziţie numită poziţia curentă
7
FLUX

 La deschidere, fiecărui fişier i se asociază o structură de


date de tipul FILE şi se alocă o zonă de memorie tampon
pentru transferuri de date de la/către fişier

 Structura FILE este definită în stdio.h şi conţine informaţii


specifice fişierului (versiunile noi au adăugat și alte
informații):
 dimensiunea fişierului, locaţia curentă, ...

8
typedef struct {
int level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
int bsize; /* Buffer size */
unsigned char _FAR *buffer; /* Data transfer buffer */
unsigned char _FAR *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE; /* This is the FILE object

Borland 9
typedef struct
{
char* _ptr;
int _cnt;
char* _base;
int _flags;
int _file;
int _charbuf;
int _bufsiz;
char* _tmpfname;
}FILE;

Visual Studio

10
FLUX
 unde câmpul flags conţine următoarele informaţii:
_F_RDWR Read and write
_F_READ Read-only file
_F_WRIT Write-only file
_F_BUF Malloc'ed buffer data
_F_LBUF Line-buffered file
_F_ERR Error indicator
_F_EOF EOF indicator
_F_BIN Binary file indicator
_F_IN Data is incoming
_F_OUT Data is outgoing
_F_TERM File is a terminal

11
FLUX
 Streamurile standard au tipul pointer la structura FILE
(FILE *) şi pot fi utilizate cu orice funcţie care lucrează
cu fişiere:
 programatorul poate utiliza aceste fluxuri, dar nu le poate
modifica

 Limbajul C nu face distincţie între operaţiile de I/E cu


fişiere şi cele cu consola

 Fişierele pot fi tratate în două moduri:


 la nivel inferior:
 tratare dependentă de SO;
 funcţiile aferente sunt descrise în io.h, stat.h, fcntl.h

 la nivel superior:
 se folosesc funcţii ce au la bază structura FILE definită
în stdio.h 12
2. OPERAŢII PE FIŞIERE
Deschiderea unui fişier

FILE * fopen(const char *spec_fis, const char *mod);

 funcţia deschide fişierul cu numele specificat de


parametrul spec_fis (nume şi cale), în modul de acces
dat de parametrul mod
 returnează un pointer la structura FILE în caz de succes
sau valoarea NULL în caz de eşec
 pointerul returnat va fi folosit de alte funcţii pentru fişiere
(citire, scriere,...)
13
OPERAŢII PE FIŞIERE
Moduri de acces:
 pentru fişiere text:
 "r" citire (deschidere)
 "w" scriere (creare)
 "a" adăugare (append)
 "r+" citire/scriere (nu creează fişier dacă acesta nu
există şi nu distruge fişierul dacă acesta există)
 "w+" citire/scriere (creează fişier dacă acesta nu
există şi distruge fişierul dacă acesta există)
 "a+" citire/scriere (creează fişier dacă acesta nu
există şi adaugă înregistrări la sfârşitul acestuia
dacă fişierul există)

 Se poate adăugă litera ‘t’ în şirul de caractere pentru a specifica


explicit că se lucrează cu fişiere text (de exemplu "at")
14
OPERAŢII PE FIŞIERE
 Moduri de acces:
 pentru fişiere binare:
 "rb" citire binară (deschidere)
 "wb" scriere binară (creare)
 "ab" citire/scriere binară (adăugare)
 "r+b" citire/scriere binară
 "w+b" citire/scriere binară
 "a+b" citire/scriere binară

15
OPERAŢII PE FIŞIERE
 Se recomandă testarea pointerului returnat de funcţie înainte
de a fi folosit în alte funcţii pentru fişiere
 La deschiderea unui fişier disc se iniţializează o variabilă
index care indică poziţia curentă în fişier:
 dacă modul de acces este în citire sau scriere, iniţializarea se
face cu 0
 dacă modul de acces este în adăugare, inţializarea se face cu
numărul de octeţi din fişier

 Funcţiile de citire/scriere realizează transferuri de date


începând cu octetul situat la poziţia curentă

 După fiecare transfer se avansează indicatorul de poziţie cu


numărul de octeţi transferaţi
16
OPERAŢII PE FIŞIERE

Exemple C/C++ standard

FILE *fp;
char nume_fis[ ] = "Readme.txt";

if((fp = fopen(nume_fis, "r") != NULL) {


// operatii de citire pe fisier
}
else {
cout << "Eroare la deschiderea fisierului : "
<< nume_fis;
exit(1);
}
...

17
MICROSOFT VC++1Y
errno_t fopen_s( FILE** pFile, const char *filename, const
char *mode );

Parametri:
 pFile – pointer la pointerul de tip FILE care primeşte
pointerul la fişierul deschis.
 filename –numele fișierului.

 mode –tipul de acces permis.

Valoarea returnată:
 zero pentru succes; cod de eroare la eşec. Vedeți errno,
_doserrno, _sys_errlist, și _sys_nerr pentru mai multe
informaţii despre aceste coduri de eroare 18
 fopen_s() suportă fluxuri Unicode. Pentru a deschide
un fişier Unicode nou sau existent, se trimite un flag
ccs care specifică codarea dorită către fopen_s():
fopen_s(&fp, "newfile.txt", "rw, ccs= encoding ");

 Valorile permise pentru encoding sunt


UNICODE, UTF-8 si UTF-16LE. Dacă nu se specifică
nici o valoare pentru codare, se utilizează codarea
ANSI.

19
#include <stdio.h>
int main(void) {
FILE *stream;
errno_t err;
err = fopen_s(&stream, "d:/test", "w+");
if(err == 0) {
printf("S-a deschis fisierul \'test\' \n");
}
else {
printf("Fisierul \'test\' nu s-a deschis\n");
}
}
20
OPERAŢII PE FIŞIERE
Observaţii:
 In şirul de caractere ce dă numele şi calea către fişier,
caracterul '\' se reprezintă prin secvenţa de evitare '\\‘
sub SO Windows. Se poate folosi ‘/’ sub orice SO.
 SO nu face distincţie între literele mari şi cele mici
 Nu pot fi deschise simultan oricâte fişiere:
 numărul maxim de fişiere este precizat în variabile de stare
ale SO

21
OPERAŢII PE FIŞIERE

Inchiderea unui fişier

int fclose(FILE *fp);


int _fcloseall( void ); //VC++1y

 fclose() returnează 0 dacă fluxul este închis cu


succes
 _fcloseall() returnează numărul total de fluxuri
închise
 Ambele funcţii returnează EOF(-1) în caz de eşec

22
OPERAŢII PE FIŞIERE

Observaţii:
 Bufferele cu care lucrează funcţiile pentru fişiere au
aceeaşi dimensiune cu cantitatea de informaţii ce
poate fi scrisă fizic pe disc într-o singură operaţie
 Scrierea are loc efectiv doar când bufferul este plin
 Dacă bufferul nu este plin, apelul funcţiei fclose( )
determină scrierea conţinutului bufferului pe disc
 La închiderea unui fişier se eliberează şi bufferul
asociat fişierului
 La terminarea programului prin apelul funcţiei exit( )
se închid toate fişierele deschise
23
EXEMPLU VC++1Y
// Deschide 2 fisiere . Foloseste fclose() pentru a inchide unul si //_fcloseall()
pentru a inchide tot ce mai ramane deschis

#include <stdio.h>
#include <conio.h>
FILE *stream, *stream2;
int main( void ){
errno_t err;
// deschidere pentru citire
err = fopen_s( &stream, "D:/CPP/Source.cpp", "r" );
if( err == 0 )
printf("Fisierul 'Source.cpp' a fost deschis\n" );
else
printf("Fisierul 'Source.cpp' nu a fost deschis\n" );
24
// Deschidere pentru scriere
err = fopen_s( &stream2, "D:/CPP/data2.dat", "w+" );
if( err == 0 )
printf( " Fisierul 'data2.dat' a fost deschis \n" );
else
printf( " Fisierul 'data2.dat' nu a fost deschis\n" );
// inchide fluxul
if( stream ) {
err = fclose( stream );
if ( err == 0 )
printf( " Fisierul 'Source.cpp' a fost inchis\n" );
else
printf( "Fisierul 'Source.cpp' nu a fost inchis\n" );
}
// se inchid celelalte fisiere
int numclosed = _fcloseall( );
printf("Numarul de fisiere inchise de _fcloseall: %u\n",
numclosed );
}
25
OPERAŢII PE FIŞIERE
Prelucrări la nivel de caracter (cuvânt)
int fputc(int c, FILE *stream); // functie
int putc(int c, FILE *fp); // posibil implementat ca macro

 Acţiuni:
 se scrie caracterul c în fişierul asociat lui fp
 se returnează valoarea scrisă sau EOF în caz de eşec

 Deşi primul parametru are tipul int se foloseşte doar


octetul inferior al parametrului
 După scrierea caracterului este actualizată poziţia
curentă în fişier
 In stdio.h se defineşte funcția macro putchar pentru
scrierea caracterelor la ieşirea standard (stdout):
26
#define putchar(c) putc(c, stdout)
OPERAŢII PE FIŞIERE
Prelucrări la nivel de caracter (cuvânt)
int fgetc(FILE *fp);
int getc(FILE *fp);

 Acţiuni:
 citeşte un caracter din fişierul specificat prin parametrul fp
 returnează codul ASCII al caracterului sau EOF în caz de eşec
 După citirea unui caracter se avansează poziţia curentă
în fişier
 In stdio.h se defineşte macroul getchar pentru citirea
caracterelor de la intrarea standard (stdin):
#define getchar( ) getc(stdin)
 La nivel de cuvânt (2-4 octeţi) există următoarele funcţii
(pentru lucrul cu intregi, fisiere binare):
int putw(int i, FILE *fp);
27
int getw(FILE *fp);
!!! _putw(), respectiv _getw() in VS 2019.
OPERAŢII PE FIŞIERE
/*copiaza un fisier caracter cu caracter intr-un fisier destinatie */

#include <stdio.h>
int main(void){
FILE *fps, *fpd;
char c;
char fiss[ ] = "D:/CPP/Source.cpp";
char fisd[ ] = "D:\\CPP\\Fis2.txt";
errno_t err;
if((err = fopen_s(&fps, fiss, "rb") != 0)) {
puts("Eroare la deschiderea fisierului sursa !");
return 1; }
if((err = fopen_s(&fpd,fisd, "wb") != 0)) {
puts("Eroare la deschiderea fisierului destinatie!");
return 1; }
while((c = getc(fps)) != EOF) putc(c, fpd);
fclose(fpd);
fclose(fps);
return 0; }
28
/*afiseaza caracter cu caracter un fisier cu numele citit din linia de c-da */

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[ ]){
FILE *fp;
errno_t err;
char c;
if(argc == 2) {
err = fopen_s(&fp, argv[1], "r");
if((err != 0)){
printf("\nEroare la deschiderea fisierului : %s\n",
argv[1]);
exit(1);
}
while((c = fgetc(fp)) != EOF) fputc(c, stdout);
fclose(fp);
} 29
else printf("\nEnd program");
}
OPERAŢII PE FIŞIERE
Intrări/ieşiri de şiruri de caractere
int fputs(const char *str, FILE *fp);
 Acţiuni:
 scrie şirul de caractere specificat de str în fişierul specificat
de fp
 returnează codul ASCII al ultimului caracter scris în fişier sau
valoarea EOF în caz de eşec

 Şirul trebuie să se termine cu caracterul '\0' (NULL),


dar acest caracter nu este scris în fişier
 Funcţia fputs( ) nu adaugă la sfârşit secvenţa CR/LF,
cum face funcţia puts( )

30
OPERAŢII PE FIŞIERE
Intrări/ieşiri de şiruri de caractere
char *fgets(char *str, int n, FILE *fp);
 Acţiuni:
 citeşte cel mult (n-1) caractere din fişierul precizat de fp în şirul
specificat de pointerul str
 returnează un pointer la şirul în care se depun caracterele sau
valoarea NULL în caz de eroare
 şirul este completat cu caracterul '\0'

 Funcţia fgets( ) întrerupe citirea dacă:


 s-au citit (n-1) caractere
 s-a întâlnit caracterul '\n' (NL)

 s-a ajuns la sfârşit de fişier (EOF)

 La întâlnirea caracterului '\n' funcţia fgets( ) îl reţine în şir,


spre deosebire de funcţia gets( ) care nu face acest lucru
 Funcţia fgets( ) este utilă pentru citirea linie cu linie a unui
fişier text 31
OPERAŢII PE FIŞIERE
// Copierea unui fisier sursa intr-un fisier destinatie, linie cu linie
#include <stdio.h>
#include <stdlib.h>

#define DIML 81

int main(void){
FILE *fps, *fpd;
errno_t err;
char buf[DIML], *p;
char fiss[ ] = "D:/CPP/Source.cpp", fisd[ ] =
"D:/CPP/fis3.txt";
// deschidere fisier sursa
if((err = fopen_s(&fps, fiss, "r") != 0)){
puts("Eroare la deschiderea fisierului sursa !");
exit(1); 32
}
OPERAŢII PE FIŞIERE
// deschidere fisier destinatie
if((err = fopen_s(&fpd, fisd, "w") != 0)){
puts("Eroare la deschiderea fisierului destinatie!");
exit(1);
}
//citire date din fisierul sursa
while((p = fgets(buf, DIML, fps)) != NULL)
fputs(buf, fpd); // scriere date destinatie
// inchidere fisiere
fclose(fpd);
fclose(fps);
puts("Copiere terminata");
}

33
OPERAŢII PE FIŞIERE
Intrări/ieşiri cu format

int fprintf(FILE *fp, const char *format [,lista_expresii]);

 Acţiuni:
 converteşte datele din format intern în format extern
(ASCII) şi le scrie în fişierul indicat de pointerul fp
 returnează numărul caracterelor scrise în fişier sau
o valoare negativă (-1) în caz de eroare

34
OPERAŢII PE FIŞIERE

FILE *fp;
int i = 100;
char c = 'C';
...
fp = fopen("Test.txt", "w+");
fprintf(fp, "%d %c", i, c);
...
fclose(fp);

35
FISIERE IN VISUAL STUDIO C++1Y -EXEMPLE
#include <stdio.h>
#include <stdlib.h>
//fopen_s - VC++13

int main(void){
FILE *fps, *fpd;
char c;
char fis_s[] = "fis1.txt", fis_d[] = "fis2.txt";
// fisiere din directorul curent
errno_t err;
// deschidere fisier sursa
err=fopen_s(&fps, fis_s, "w");

36
if(err!=0) {
puts("Eroare la creare fisierului sursa !");
exit(1); }
fprintf(fps,"ttt");
fclose(fps);
err=fopen_s(&fps, fis_s, "r");
if(err!=0){
// fis1.txt va fi in directorul unde se afla
fisierul sursa *.cpp
puts("Eroare la deschiderea fisierului sursa !");
exit(1);
}
// deschidere fisier destinatie
err=fopen_s(&fpd, fis_d, "w");

37
if(err!=0) {
puts("Eroare la deschiderea fisierului destinatie!");
exit(1);
}
while((c = getc(fps)) != EOF) // citire caractere din fisierul sursa
putc(c, fpd); // scriere caractere in fisierul destinatie
// inchidere fisiere
fclose(fps);
fclose(fpd);
puts("Copiere terminata in fis2.txt");
}

38
OPERAŢII PE FIŞIERE

Intrări/ieşiri cu format

int fscanf(FILE *fp, const char *format, lista_adrese);

 Acţiuni:
 citeşte caractere din fişierul indicat de pointerul fp
şi le converteşte din formatul extern în formatul
intern
 returnează numărul câmpurilor citite corect sau
EOF în caz de eroare sau dacă s-a ajuns la
sfârşitul fişierului

 Există și varianta cu facilități de securitare


fscanf_s(). 39
int i; OPERAŢII PE FIŞIERE
...
printf("Introduceti un numar intreg : ");
if (fscanf(stdin, "%d", &i))
printf("S-a introdus numarul : %i\n", i);
else {
fprintf(stderr, "Eroare la citirea unui intreg de
la consola !\n");
exit(1);
}

 Specificatorii de format sunt aceeaşi ca şi în cazul funcţiilor


printf( ) şi scanf( )
!!! Compilatoarele VC++1y/2z ofera functia fscanf_s(), ca
un mecanism de securitate/optimizare in cadrul 40
platformei.
/* exemplu fscanf_s */
#include <stdio.h>
#include <stdlib.h>

int main (){


char str [80];
float f;
FILE * pFile;
int err;
err = fopen_s (&pFile, "myfile.txt","w");
if(err==0){
fprintf (pFile, "%f %s", 3.1416, "PI-Omega");
fclose(pFile);
}
else { puts("\nEroare la crearea fisierului");
exit(1); 41

}
err = fopen_s(&pFile, "myfile.txt","r");
if(err==0){
fscanf_s(pFile, "%f", &f);
fscanf_s(pFile, "%s", str, _countof(str));
fclose(pFile);
printf("S-a citit din fisier: %f and %s \n", f, str);
}
else {
puts("\nEroare la deschiderea fisierului");
exit(1);
}
}

42
OPERAŢII PE FIŞIERE
Operaţii de formatare în memorie (in şiruri de caractere)

int sprintf(char *buf, const char *format [,lista_expresii]);

 Acţiuni:
 valorile rezultate în urma conversiei din formatul
intern în formatul extern sunt scrise în şirul de
caractere specificat de parametrul buf
char buffer[80];
...
sprintf(buffer, "Pi = %f\n", M_PI);
puts(buffer);

In Visual Studio este recomandată utilizarea functiei cu


facilități de securitate sprintf_s() (de la versiunea C11)43
#include <stdio.h>
#include<conio.h>
int main(){
char buffer[100];
int an = 1, n;
float med = 9.66f;
char nume[] = "Mihai";
n = sprintf_s(buffer, "Studentul %s din anul %d are
media %.2f", nume, an, med);
printf(buffer);
printf("\n[%s] este un sir de caractere cu lungimea
%d\n", buffer, n);
}

44
OPERAŢII PE FIŞIERE

int sscanf(char *buf, cons char *format, lista_adrese);

 Acţiuni:
 datele în format ASCII din şirul de caractere
precizat de pointerul buf sunt preluate, convertite şi
înscrise la adresele specificate în lista de parametri

Este recomandată utilizarea funcției cu facilități de securitate


sscanf_s() (de la versiunea C11)

45
#include<stdio.h>

int main(){
char str[200];
char nume[20], prf[20];
int v;
float g;

printf("Introduceti intr-un rand numele, profesia,


varsta si greutatea:\n");
scanf_s("%[^\n]s", str, sizeof(str));
sscanf_s(str,"%s %s %d %f", nume, sizeof(nume), prf,
sizeof(prf),&v, &g);

printf("\nNumele: %s", nume);


printf("\nProfesia: %s", prf);
printf("\nVarsta: %d", v);
printf("\nGreutatea: %.2f", g); 46

}
OPERAŢII PE FIŞIERE
Citirea şi scrierea datelor binare
 In cazul fişierelor binare nu se interpretează conţinutul
informaţiei
 O înregistrare într-un fişier binar este o colecţie de
articole:
 articolul este o dată predefinită sau definită de utilizator (de
exemplu octeţi, cuvinte, structuri,...)

 La citire se transferă din fișier, în zona tampon


asociată fişierului, un număr de articole de lungime
fixă
 La scriere se transferă din zona tampon în fișier un
număr de articole de lungime fixă
 In acest fel se pot transfera cel mai bine date 47
numerice sau date structurate (tablouri, structuri,...)
OPERAŢII PE FIŞIERE

size_t fread(void *buffer, size_t dim, size_t nr_art, FILE *fp);


size_t fwrite(const void *buffer, size_t dim, size_t nr_art, FILE *fp);

 size_t este definit în fişierul antet stdio.h şi poate fi tipul


unsigned sau unsigned long
 buffer este un pointer generic spre zona de memorie din
care se vor citi sau în care se vor scrie articolele
 dim precizează dimensiunea unui articol, în octeţi
 nr_art specifică câte articole se vor citi sau scrie
 fp precizează fişierul în care/din care se transferă datele

48
OPERAŢII PE FIŞIERE

 Funcţia fread( ) returnează numărul articolelor citite


corect. Dacă valoarea returnată diferă de nr_art (al 3-lea
parametru), înseamnă că a apărut o eroare la citire, sau
s-a detectat sfârșitul de fișier. În acest caz vor fi setați
indicatorii ocrespunzători, de eroare sau de sfârșit de
fișier (pot fi testați cu funcțiile ferror(), respectiv feof())

 Funcţia fwrite( ) returnează numărul articolelor scrise.


Dacă această valoare diferă de nr_art, înseamnă că a
apărut o eroare la scriere și va fi setat indicatorul de
eroare

 Ambele funcţii actualizează poziţia curentă în fişier cu


valoarea dim*nr_art 49
/* Creare fisier binar */
#include <stdio.h>
#include <iostream>
#include <conio.h>
using namespace std;
struct datac {
int zi;
char luna[11];
int an; };

int main(void){
errno_t err;
FILE *fp;
char nume_fis[ ] = "D:/CPP/Date_cal.dat";
int n;
struct datac str;

if((err = fopen_s(&fp, nume_fis, "wb") != 0)) {


cout << "Eroare deschidere fisier !"; exit(1);
50
}
cout << "Numar date calendaristice : ";
cin >> n;

// citire date de la consola


for(int i=0; i<n; i++) {
cout << "\nData " << i << " : ";
cout << "\tZiua : ";
cin >> str.zi;
cout << "\tLuna : ";
cin >> str.luna;
cout << "\tAnul : ";
cin >> str.an;
fwrite(&str, sizeof(datac), 1, fp);
}
51
fclose(fp);
/* citirea fisierului scris anterior */

if ((err = fopen_s(&fp, nume_fis, "rb") != 0)) {


cout << "Eroare deschidere fisier !";
exit(1);
}

// cat timp nu e sfarsit de fisier si nici eroare de


// citire
while (fread(&str, sizeof(datac), 1, fp)==1) {
cout << str.an << " " << str.an << " "<<str.zi
<< endl;
}

fclose(fp);
} 52
OPERAŢII PE FIŞIERE

Funcţia feof( )
int feof(FILE *fp);

 Permite testarea sfârşitului de fişier (EOF)


 De fapt este testat indicatorul _F_EOF din structura
FILE, indicator care este setat la întâlnirea sfârşitului
de fişier în urma unei operaţii de citire
 Returnează o valoare nenulă dacă s-a ajuns la
sfârşitul fişierului asociat pointerului fp sau valoarea 0
în caz contrar

53
OPERAŢII PE FIŞIERE
Golirea zonei tampon
int fflush(FILE *fp);

 Descriere:
 în cazul unui fişier deschis pentru scriere se forţează scrierea pe
disc (golirea sau vidarea bufferului), chiar dacă zona tampon nu
este plină
 În unele implementări (unele compilatoare), în cazul unui fişier
deschis pentru citire se şterge zona tampon asociată şi se pierd
datele

 Funcţia returnează valoarea 0 în caz de succes sau valoarea -1 în


caz de eşec
 Exemplu: golirea buferului de tastatură de eventualele caractere
eronate rămase în buffer. Nu funcționează pe toate compilatoarele.
char c;
...
fflush(stdin);
scanf("%c", &c); 54
OPERAŢII PE FIŞIERE

Golirea zonei tampon


int _flushall( );

 Şterge buferele pentru fişierele deschise în citire şi


goleşte buferele pentru fişierele deschise în scriere
 Returnează numărul total de fişiere deschise

55
OPERAŢII PE FIŞIERE

Accesul aleator la fişiere


 Unele dispozitive periferice (de exemplu discul)
permit accesul aleator la date
 atât în ceea ce priveşte accesul aleator la fişiere
 dar şi în ceea ce priveşte accesul aleator la date în
cadrul unui fişier

 Pentru a realiza acest lucru trebuie gestionată


poziţia curentă din fişier

56
OPERAŢII PE FIŞIERE

 long int ftell(FILE *fp);


 Permite citirea indicatorului de poziţie
 Funcţia returnează poziţia curentă din fişierul precizat de
pointerul fp în caz de reuşită sau valoarea -1L în caz de
eşec

 int fgetpos(FILE *fp, long int *poz);


 Se citeşte valoarea poziţiei curente şi se înscrie în
variabila poz
 Se returnează valoarea 0 în caz de succes

 int fsetpos(FILE *fp, const long int *poz);


 Se atribuie valoarea variabilei poz indicatorului de poziţie
asociat fişierului indicat de pointerul fp
 Se returnează valoarea 0 în caz de succes 57
OPERAŢII PE FIŞIERE
 int fseek(FILE *fp, long nr_oct, int origine);
 Se deplasează indicatorul de poziţie din poziţia origine cu
un număr de octeţi nr_oct
 Se returnează valoarea 0 în caz de reuşită sau o valoare
nenulă în caz de eşec
 Poziţia de referinţă "origine" poate avea următoarele valori:
 0 = SEEK_SET : început de fişier

 1 = SEEK_CUR : poziţia curentă

 2 = SEEK_END : sfârşit de fişier

 void rewind(FILE *fp);


 Permite poziţionarea indicatorului de poziţie la începutul
fişierului
 Se şterge şi indicatorul de eroare asociat fişierului
 Acelaşi lucru se poate face şi astfel:
fseek(fp, 0L, SEEK_SET);
58
OPERAŢII PE FIŞIERE

long filesize(FILE *fp)


{
long current_pos, length;

current_pos = ftell(fp);
fseek(fp, 0L, SEEK_END);
length = ftell(fp);
fseek(fp, current_pos, SEEK_SET);
return(length);
}

59
OPERAŢII PE FIŞIERE
Alte funcţii
 int ferror(FILE *fp);
 Returnează o valoare nenulă dacă în fişierul indicat
de pointerul fp a apărut o eroare sau valoarea 0 în
caz contrar
 informaţiile se referă la ultimul acces la fişier

 de fapt, se consultă indicatorul de eroare


_F_ERR asociat fişierului, indicator stocat în
structura FILE

 Odată setat, indicatorul de eroare rămâne setat până


la apelul funcţiei clearerr( ) sau rewind( ) sau până la
închiderea fişierului

 void clearerr(FILE *fp);


 Se şterge indicatorul de sfârşit de fişier, precum şi 60
indicatorul de eroare
CITIRE FISIER BINAR CREAT IN PREALABIL
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
struct datac {
int zi;
char luna[11];
int an;};
int main(void){
FILE *fp;
errno_t err;
char nume_fis[ ] = "D:/CPP/Date_cal.dat";
//!!! de introdus in fisier date calendaristice
int n, dim;
struct datac str;
if((err = fopen_s(&fp,nume_fis, "rb") != 0)){
cout << "Eroare deschidere fisier !"; 61
exit(1);}
cout << "Index data calendaristica : ";
cin >> n;
fseek(fp, (n-1)*sizeof(datac), SEEK_SET);
dim = fread(&str, sizeof(datac), 1, fp);
cout <<"\ndim="<<dim<<endl; // 1 articol la str
if(ferror(fp)) {
printf("Erroare citire date sursa.\n");
exit(1);
}
cout << "\nData nr. : " << n ;
cout << "\tZiua : " << str.zi;
cout << "\tLuna : " << str.luna;
cout << "\tAnul : " << str.an;
fclose(fp);
62
}
63
GENERARE NUMERE ALEATOARE INTR-UN FISIER
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void generare(FILE *fp, int n);
int main(){
FILE *fp;
int n, buf1[100], i=0;
char sp[20];
errno_t err;
printf("Introduceti un nume de fisier:\n");gets(sp);
printf("Cate valori ? ");
scanf("%d",&n);
err=fopen_s(&fp,sp,"w+b");
if (err!=0) {
64
puts("\n Nu s-a putut deschide fisierul");
exit(1); }
OPERAŢII PE FIŞIERE
generare(fp, n);
fseek(fp,0L,SEEK_SET);
while(fread(&buf1[i],sizeof(int),1,fp)==1){
printf("%4d",buf1[i]);
i++;
}
printf("\n");
fclose(fp);
}
void generare(FILE * pf, int n){
int buf2[100];
int RANGE_MIN = 0, RANGE_MAX = 100;
srand((unsigned)time(NULL));
for(int i=0; i<n; i++) {
buf2[i]=(((double)rand()/(double)RAND_MAX)*RANGE_MAX+
RANGE_MIN);
fwrite(&buf2[i],sizeof(int),1,pf); 65
}
}
66
După acest curs stim…
 Cum se realizează operațiile cu fișiere în C: fluxuri
text, binare, tratare la nivel inferior, superior
 Deschiderea fișierelor și închiderea fișierelor

 Operații pe fisiere text: pe caracter (putc()/fputc(),


getc(), fgetc()), șiruri de caractere (fputs(), fgets()),
date de tip predefinit (fprintf(), fscanf())
 Operații pe fișiere binare, funcțiile de citire/scriere
(fread(), fwrite())
 Funcții de testare a indicatorilor de eroare și sfârșit
de fișier, de ștergere a indicatorilor
 Accesul aleator la fișiere (fseek(), ftell(), fgetpos(),
fsetpos())
67
68

S-ar putea să vă placă și