Documente Academic
Documente Profesional
Documente Cultură
Fluxuri în C++
Cuprins
Obiective ......................................................................................................................................
U8.1. Fluxuri în C++. Generalităţi ...............................................................................................
U8.2. Ierarhia streambuf ...............................................................................................................
U8.3. Ierarhia ios...........................................................................................................................
Ne propunem să studiem două ierarhii de clase: streambuf şi ios pentru o mai bună
înţelegere a modului de lucru cu fluxuri în C++.
Din clasa streambuf sunt derivate două clase: filebuf (care gestionează buffer-ele pentru
fluxurile de fişiere) şi strstreambuf care gestionează buffer-ele pentru fluxurile de lucru cu
string-uri:
streambuf
filebuf strstreambuf
streambuf()
streambuf(char *s,int n)
filebuf()
filebuf(int fd)
filebuf(int fd,char *s,int n)
Primul constructor crează un buffer de fişier, dar nu-l asociază cu nici un fişier.
Al doilea constructor crează un buffer şi îl asociază unui fişier având descriptorul fd, care
este un număr întreg.
Al treilea constructor crează un buffer de caractere al cărui adresă de memorie este s,
buffer-ul are lungimea n, iar constructorul asociază acest buffer unui fişier cu descriptorul fd.
Clasa filebuf are un destructor care închide eventualul fişier asociat fluxului:
~filebuf()
Clasa strstreambuf este scrisă pentru operaţii de intrare / ieşire în / din zone de memorie
RAM. Clasa are 5 constructori şi nici un destructor.
Ierarhia de clase pornită de ios este scrisă pentru a lucra cu fluxuri de date. Transmiterea
şi primirea datelor se face prin intermediul unei zone tampon prelucrate prin intermediul unui
obiect instanţă al unei clase din ierarhia streambuf.
Clasa ios are 2 constructori:
ios(streambuf *buf)
ios()
Primul constructor asociază un buffer buf, obiect al clasei streambuf unui flux,
constructorul primeşte ca argument adresa spre obiectul de tip buffer cu care va lucra fluxul. Al
doilea constructor crează un obiect al clasei ios, fără a-l lega la un buffer. Legarea se poate face
ulterior cu ajutorul funcţiei init, care este membră clasei ios.
Clasa ios conţine următoarele câmpuri:
1) int bad() returnează o valoare întreagă nenulă dacă a apărut cel puţin o eroare în
prelucrarea fluxului. Verificarea se face interogând biţii ios::badbit şi ios::hardfail ai valorii din
câmpul state al clasei ios.
2) void clear(int st=0); setează câmpul state la valoarea întreagă primită ca argument.
Dacă st este 0 (valoare de altfel implicită), atunci starea fluxului se iniţializează din nou ca fiind
bună. Un apel de forma flux.clear() readuce fluxul în stare bună (fără erori).
3) int eof() returnează o valoare nenulă, dacă nu mai sunt date în flux (sfârşit de fişier).
De fapt funcţia interoghează bitul ios::eofbit al câmpului state.
4) int fail() returnează o valoarea nenulă, dacă o operaţie aplicată fluxului a eşuat. Se
verifică biţii ios::failbit, ios::badbit şi ios::hardfail ai câmpului state (în plus faţă de funcţia bad
verifică şi bitul ios::failbit).
5) char fill() returnează caracterul de umplere al spaţiile libere de la scrierea formatată.
6) char fill(char c) setează caracterul de umplere al spaţiile goale de la scrierea formatată
la valoarea c şi returnează caracterul folosit anterior în acest scop.
7) long ios_flags() returnează valoarea reţinută în x_flags.
8) long ios_flags(long flags) setează câmpul x_flags la valoarea primită ca argument şi
returnează vechea valoare.
9) int good() returnează o valoare nenulă dacă nu au apărut erori în prelucrarea fluxului.
Acest lucru se realizează consultând biţii câmpului state.
10) void init(streambuf *buf); transmite adresa buffer-ului de tip streambuf cu care va
lucra fluxul.
11) int precision(int p); setează precizia de tipărire a numerelor reale la valoarea primită
ca argument şi returnează vechea valoare. De fapt câmpul ios::precision se seteaza la valoarea p
şi se returnează vechea sa valoare.
12) int precision() returnează valoarea preciziei la tipărire a valorilor reale (reţinută în
câmpul ios::precision).
13) streambuf* rdbuf() returnează adresa către obiectul responsabil cu buffer-ul fluxului.
14) int rdstate() returnează starea fluxului (valoarea câmpului state).
15) long setf(long setbits, long field); resetează biţii (îi face 0) din x_flags pe poziţiile
indicate de biţii cu valoare 1 ai parametrul field şi apoi setează biţii din x_flags la valoarea 1 pe
poziţiile în care biţii sunt 1 în parametrul setbits. Funcţia returnează vechea valoare a lui x_flags.
16) long setf(long flags) modifică biţii câmpului x_flags la valoare 1 pe poziţiile în care
biţii parametrului flags sunt 1 şi returnează vechea valoare a lui x_flags.
17) void setstate(int st); setează biţii câmpului state la valoarea 1 pe poziţiile în care biţii
parametrului st sunt 1.
18) void sync_with_stdio(); sincronizează fişierele stdio cu fluxurile iostream. În urma
sincronizării viteza de execuţie a programului scade mult.
19) ostream* tie() returnează adresa către fluxul cu care se afla legat fluxul curent. De
exemplu, fluxurile cin şi cout sunt legate. Legătura dintre cele două fluxuri constă în faptul că
atunci când unul dintre cele două fluxuri este folosit, atunci mai întâi celălalt este golit. Dacă
fluxul curent (din care este apelată funcţia tie) nu este legat de nici un flux, atunci se returnează
valoarea NULL.
20) ostream* tie(ostream* fl) fluxul fl este legat de fluxul curent, cel din care a fost
apelată această funcţie. Este returnat fluxul anterior legat de fluxul curent. Ca efect al legării unui
flux de un alt flux este faptul că atunci când un flux de intrare mai are caractere în buffer sau un
flux de ieşire mai are nevoie de caractere, atunci fluxul cu care este legat este întâi golit. Implicit,
fluxurile cin, cerr şi clog sunt legate de fluxul cout.
21) long unsetf(long l) setează biţii din x_flags la valoarea 0 pe pozitiile în care
parametrul l are biţii 1.
22) int width() returnează lungimea pe care se face afişarea formatată.
23) int width(int l); setează lungimea pe care se face afişarea formatată la valoarea
primită ca argument şi returnează vechea valoare.
Din clasa ios sunt derivate 4 clase: istream, ostream, fstreambase şi strstreambase:
ios
Clasa istream realizează extrageri formatate sau neformatate dintr-un buffer definit ca
obiect al unei clase derivate din streambuf.
Constructorul clasei istream este:
istream(strstream *buf);
Constructorul asociază un obiect de tip buffer buf, primit ca argument, unui flux de
intrare.
Funcţiile membre clasei istream:
În clasa istream este supraîncărcat şi operatorul >> pentru extragere de date în modul
text din fluxul de intrare.
Clasa ostream realizează introduceri formatate sau neformatate într-un buffer definit ca
obiect al unei clase derivate din streambuf. Clasa are un singur constructor cu următoarea
structură:
ostream(streambuf* buf);
Constructorul asociază un buffer, obiect al unei clase derivate din streambuf, fluxului de
ieşire.
Metodele clasei ostream sunt:
În clasa ostream este supraîncărcat operatorul << pentru introducere de valori în modul
text în flux.
Clasa iostream este derivată din clasele istream şi ostream şi are ca obiecte fluxuri care
suportă operaţii de intrare şi ieşire. Clasa iostream are un singur constructor care asociază unui
buffer buf, obiect al clasei streambuf, un flux, obiect al clasei iostream:
iostream(streambuf* buf);
Rezumat
Am studiat pe scurt ierarhia streambuf pentru buffer-ele fluxurilor şi clasele superioare
din ierarhia ios scrise pentru prelucrarea fluxurilor. Aceste clase sunt baza prelucrării fişierelor şi
a string-urilor (capitolele următoare). Din aceste clase practic se moştenesc majoritatea datelor şi
metodelor necesare pentru a lucra cu fişiere şi string-uri.