|
Pentru ca nu exista instructiuni de intrare/iesire, s-au definit functii (in C), respectiv doua ierarhii de clase (in C++). Aceste doua ierarhii (reprezentate in figurile de mai jos si declarate in fisierul iostream.h) realizeaza operatiile de intrare/iesire prin stream-uri (flux de date sursa destinatie
Clasa streambuf se foloseste pentru gestionarea zonelor tampon si operatii de intrare/iesire simple.
|
Clasa ios este clasa de baza vituala pentru clasa istream (care face conversia dupa un format specificat, din caracterele unui obiect de tip streambuf), clasa ostream (care face conversia dupa un format specificat, in caractere ale unui obiect de tip streambuf) si clasa iostream (care face conversii in ambele sensuri). Legatura dintre cele doua ierarhii se realizeaza printr-o data membru a clasei ios (pointer la streambuf).
Clasele derivate din clasa istream sau ostream se numesc clase stream iar obiectele claselor derivate din clasa ios se numesc streamuri. In fisierul iostream.h sunt definite streamurile cin (I istream_withassign, pentru stdin), cout (I ostream_withassign, pentru stdout), clog si cerr (I ostream_withassign, pentru stderr, cu respectiv fara zone tampon).
Operatiile de scriere se pot efectua cu operatorul de inserare << Operandul stang tre 747j97h buie sa fie un obiect al clasei ostream (sau al unei clase derivate). Pentru scrierea pe dispozitivul standard se va folosi obiectul cout. Operandul drept este o expresie pentru al carei tip a fost supraincarcat operatorul << Pentru tipurile standard a fost supraincarcat printr-o functie membru de forma:
ostream& operator << ( Tip_Standard );
Pentru tipurile abstracte programatorul poate supraincarca acest operator, asa cum se poate vedea in cele ce urmeaza
Pentru a putea tipari un obiect
cout << Obiect ;
vom supraincarcarca (intr-o prima varianta) operatorul de inserare (<<) printr-o functie prieten astfel:
class Clasa
Exemplu:
Program Operator << Friend;
#include <iostream.h> #include <conio.h>
class Q
friend ostream& operator << ( ostream& s, Q r )
};
void main (void)
// Rezultate:
r = 12/13
Se observa ca acest operator se poate aplica inlantuit pentru ca functia prieten returneaza o referinta la stream-ul curent.
In cele ce urmeaza vom da o alta rezolvare fara a utiliza o functie prieten (care micsoreaza gradul de protectie a datelor). Pentru o Clasa vom scrie o functie membru de Tiparire, care va fi apelata de catre functia de supraincarcare a operatorului << astfel:
class Clasa
ostream& Tiparire ( ostream& s )
ostream& operator << ( ostream&, Clasa c )
Pentru exemplul anterior (Q) programul va fi urmatorul:
Program Operator <<
#include <iostream.h>
#include <conio.h>
class Q
ostream& Tip (ostream& s)
};
ostream& operator << ( ostream& s, Q r )
void main (void)
// Rezultate:
r = 12/13
Operatiile de citire se pot efectua cu operatorul de extragere >> Operandul stang tre 747j97h buie sa fie un obiect al clasei istream (sau al unei clase derivate). Pentru citirea de la dispozitivul standard se va folosi obiectul cin. Operandul drept este o expresie pentru al carei tip (standard sau abstract) a fost supraincarcat operatorul >> . Pentru tipurile standard a fost supraincarcat printr-o functie membru de forma:
istream& operator >> ( Tip_Standard &
Pentru tipurile abstracte programatorul poate supraincarca acest operator, asa cum se poate vedea in cele ce urmeaza Pentru a putea citi un obiect
cin >> Obiect ;
vom supraincarcarca (intr-o prima varianta) operatorul de extragere (>>) printr-o functie prieten astfel:
class Clasa
Exemplu:
Program Operator >> Friend;
#include <iostream.h>
#include <conio.h>
class Q
friend ostream& operator << ( ostream& s, Q r )
friend istream& operator >> ( istream& s, Q& r )
void main (void)
Se observa ca acest operator se poate aplica inlantuit pentru ca functia prieten returneaza o referinta la stream-ul curent.
In cele ce urmeaza vom da o alta rezolvare fara a utiliza o functie prieten (functie care micsoreaza gradul de protectie a datelor). Pentru o Clasa vom scrie o functie membru de Citire, (care va fi apelata de catre functia de supraincarcare a operatorului >> ) astfel:
class Clasa
istream& Citire ( istream& s );
istream& operator >> ( istream&, Clasa& c
Pentru exemplul anterior (Q) programul va fi urmatorul:
Program Operator >>
#include <iostream.h>
#include <conio.h>
class Q
ostream& Tip (ostream& s)
istream& Cit (istream& s)
};
ostream& operator << ( ostream& s, Q r )
istream& operator >> ( istream& s, Q& r )
void main (void)
.
};
Atributul x_flags are o valoare implicita pentru fiecare tip standard, care se poate modifica utilizand functia membru setf descrisa in continuare.
Metoda setf are urmatoarele doua forme:
long setf (long format);
long setf (long bit, long grup);
Functia modifica atributul x_flags precizand intraga valoare (varianta a ) sau precizand un grup de biti si bitul dorit din cadrul grupului (varianta b ). Grupele (si valorile corespunzatoare) sunt adjustfield (left, right, internal), basefield (dec, oct, hex) si floatfield (scientific, fixed) In ambele variante functia returneaza valoarea anterioara a atributului x_flags. Referirea grupului si bitului dorit se face prin numele clasei urmat de operatorul de rezolutie si bitul dorit (ios::b). Valoarea atributului x_flags se poate obtine si prin apelul metodei flags (cout.flags
Atributul x_width contine lungimea minima a campului de afisare a unei date (respectiv lungimea maxima a campului din care se face citirea), avand valoarea implicita nula (afisare pe lungimea minima necesara), care se poate modifica utilizand functia membru width descrisa in continuare in ambele forme:
a) int width
b) int width (int lungime);
Functia returneaza valoarea atributului x_flags (varianta a ) sau modifica atributul x_width precizand noua valoare (lungime care poate fi o expresie) si returneaza valoarea anterioara a atributului x_width (varianta b ). Dupa fiecare transfer valoarea atributului x_flags devine nula.
Atributul x_fill contine caracterul de umplere necesar completarii campului de afisare a datei in situatia in care lungimea acestuia este mai mare decat lungimea necesara, avand valoarea implicita spatiu (' '), care se poate modifica utilizand functia membru fill
a) char fill
b) char fill (char car);
Functia returneaza valoarea atributului x_ fill (varianta a ) sau modifica atributul x_ fill precizand noul caracter de umplere (car) si returneaza valoarea anterioara (varianta b
Atributul x_precision contine precizia de afisare (numarul de zecimale) a unei date de tip real, avand valoarea implicita 0, care se poate modifica utilizand functia membru precision
a) int precision
b) int precision (int n);
Functia returneaza valoarea atributului x_ precision (varianta a ) sau modifica atributul x_ precision precizand noua precizie (p) si returneaza valoarea anterioara (varianta b
In exemplul urmator se poate vedea apelul functiilor prezentate anterior precum si rezultatele obtinute:
// Operatorul de inserare << cu format
#include <conio.h>
#include <iostream.h>
class N
istream& Cit (istream& s)
ostream& Tip (ostream& s)
operator double ( ) // N -> R
};
istream& operator >> (istream& s, N& C)
ostream& operator << (ostream& s, N C)
void main (void)
Rezultate:
Dati un numar natural : 100
Numarul natural n este: 100
Numarul natural n este: 64
Numarul natural n este: 0x64
Numarul natural n este: 100
Numarul n/3.14159 este: ____31.83
Atributele x_flags, x_width, x_fill si x_precision pot fi modificate si cu ajutorul manipulatorilor, acestia avand avantajul ca pot fi apelati inlantuit (deoarece returneaza referinta la stream). Primii sapte manipulatori prezentati in continuare sunt declarati in fisierul iostream.h, iar ultimii sase in fisierul iomanip.h :
ws setarea bitului de salt (skipws)
dec conversie in zecimal
oct conversie in octal
hex conversie in hexa
flush vidarea zonei tampon a ob.I stream
ends inserare car. Nul '0'
endl trece la rand nou si vidarea zonei tampon
setbase (int b) defineste baza in care se face conversia
setiosflags (int f) setarea unor biti precizati
resetiosflags (long f) stergerea unor biti precizati
setw (int l) defineste lungimea campului
setfill (int c) defineste caracterul de umplere
setprecision (int p) defineste numarul de zecimale
Exemplul urmator utilizeaza manipulatorii pentru a realiza tiparirea rezultatelor dorite:
// Operatorul de inserare << cu manipulatori
#include <conio.h>
#include <iostream.h>
#include <iomanip.h>
class N
istream& Cit (istream& s)
ostream& Tip (ostream& s)
operator double ( )
};
istream& operator >> (istream& s, N& C)
ostream& operator << (ostream& s, N C)
void main (void)
In exemplul urmator se utilizeaza manipulatorii pentru a realiza citirea datelor utilizand un format variabil (width(i+1)
// Operatorul de extragere >> cu manipulatori
#include <conio.h>
#include <iostream.h>
#include <iomanip.h>
class N
istream& Cit (istream& s)
ostream& Tip (ostream& s)
};
istream& operator >> (istream& s, N& C)
ostream& operator << (ostream& s, N C)
void main (void)
getche();
Daca o operatie de intrare/iesire nu s-a incheiat cu succes (nu s-a desfasurat corect, situatie in care vom spune ca streamul ajunge intr-o stare de eroare), programul poate lua o decizie (controland in acest fel desfasurarea transferurilor de date in scopul corectitudinii desfasurarii lor). Tipul erorii (un codul de retur) poate fi aflat verificand bitii datei membru state (de tip int) prin tipul enumerare io_state definit in clasa ios astfel:
class ios ;
.
};
Valorile (bitilor) atributului state se pot determina utilizand urmatoarele functii:
int good // bitii de eroare (eofbit, failbit, badbit, hardfail nu sunt setati,
int eof // este setat bitul eofbit
int fail // este setat bitul failbit sau badbit sau hardfail
int bad // este setat bitul badbit sau hardfail
int rdstate // returneaza toate valorile bitilor de stare (valoarea datei state).
Valorile bitilor datei state pot fi modificate cu functia:
void clear (int = 0);
La un apel fara paramteru actual se vor anula bitii eofbit, failbit si badbit iar pentru a preciza un anumit bit se poate folosi ca parametri actual o expresie de forma:
cin.clear (ios::nume_bit); // nume_bit restul anulati
Exemplu:
cin.clear (ios::bad_bit | cin.rdstate() ); // bad_bit restul neschimbati
Citirea (inclusiv a caracterelor albe) se poate realiza cu functia membru getline definita astfel:
istream& getline un signed char z, int n, char c 'n');
care citeste cel mult n caractere sau intalneste caracterul c.
In exemplul urmator se citesc mai multe cuvinte separate prin spatii:
class N
. }; .
void main (void)
while (!cin.eof());
In exemplul urmator se repeta citirea pana cand numarul tastat este corect:
Controlul erorilor la op. I/E
#include <conio.h>
#include <iostream.h>
class N
istream& Cit (istream& s)
ostream& Tip (ostream& s)
};
istream& operator >> (istream& s, N& C)
ostream& operator << (ostream& s, N C)
void main (void)
}
while (Gresit);
cout << ' n = ' << dec << n << endl;
getche();
Verificarea starii de eroare a unui stream se mai poate face prin operatorul sau prin conversia intr-un pointer fara tip (void
a) operatorul este supraincarcat cu metoda clasei ios:
int operator // returneaza o valoare egala cu a functiei fail();
De exemplu, in programul Propozitie.Cpp prezentat anterior instructiunea
if (cin.good()) cout << '=' << n << endl;
se poate inlocui cu
if ( cin) cout << '=' << n << endl;
sau mai simplu cu
if (cin) cout << '=' << n << endl;
b) conversia spre tipul void permite verificarea starii de eroare a stream-ului, si poate fi utilizata in constructii de forma
if ( s >> data) . ;
rezultatul (o referinta la obiectul stream I clasei istream) fiind NULL (0) daca functia fail ¹
Citirea caracterelor sau a datelor se poate realiza si cu functia membru get definita astfel:
a) int get // extrage un caracter din stream-ul curent,
b) istream& get ([un]signed char* z, int n, char c = 'n'); // nu extrage caracterul c.
In exemplul urmator se poate vedea atat utilizarea conversiei spre tipul void , precum si a functiei membru get ( in varianta b)
Controlul erorilor la op. I/E
#include <iostream.h>
#include <string.h>
class N
N::N (int c, char* mes, char* mer, char* met)
istream& N::Cit(istream& s)
return s;
istream& operator >> (istream& s, N& C)
ostream& operator << (ostream& s, N C)
void main (void)
while (!cin.eof());
|