Sunteți pe pagina 1din 7

L13 BIBLIOTECA IOSTREAM.

MANIPULATORI

Cnd se utilizeaz aceast bibliotec, se va include <iostream.h>. Fiierul iostream conine definiiile claselor care implementeaz obiecte flux i permit folosirea bufferelor. Este un echivalent al lui <stdio.h> din ANSI C. Sistemul de intrare/ieire este apt de a formata operaiile de intrare/ieire care se refer la: - precizarea dimensiunii unui cmp; - specificarea bazei unei constante numerice ntregi; - stabilirea preciziei n afiarea datelor n virgul mobil etc. Operaiile de intrare / ieire, folosind biblioteca iostream, se vor realiza prin suprancrcarea, n C++, a operatorilor << i >>. Operatorul << reprezint operaia de ieire, indicnd direcia n care se vor deplasa datele - fluxul cout. Se realizeaz o convertire automat a reprezentrii interne a unei variabile ntr-o reprezentare tip text ( a se compara cu irurile de formatare din printf ( ) din C ). Prin operatorul >> se citesc valori din fluxul cin n variabile. Se produce o convertire automat a irurilor externe la reprezentarea intern a variabilelor conform tipului lor ( a se compara cu formatarea din scanf( ) din C ). Formatarea datelor se poate realiza prin dou ci: a) acces direct la diveri membri ai clasei ios, adic se pot controla diferii indicatori pentru format definii n clasa ios, sau apelnd funcii membre ale clasei ios; b) prin funcii speciale ce se pot include n expresii de intrare / ieire, numite manipulatori. Fiecrui stream i se asociaz un set de indicatori de format, care controleaz modul n care sunt formatate informaiile de ctre stream. Ei vor fi prezeni n lanul operatorilor de ieire. n clasa ios, de regul, acestor indicatori li se atribuie cte un identificator i o valoare prin enumerare. n standardul ANSI C++, tipul indicatorilor de format este fmtflags. n mod uzual, pentru compilatoarele actuale, se folosete, pentru aceti indicatori, tipul long. Indicatorii de format asociai unui stream sunt: a) indicatori pentru alinierea ieirii: - right ( prin activarea sa se produce alinierea ieirii la dreapta); - left ( prin activarea sa se produce alinierea ieirii la stnga); n mod implicit, alinierea ieirii se face la dreapta. b) indicator pentru eliminarea spaiilor libere (blanc, tabulator, linie nou)ce preced intrarea unui stream: - skipws. c) indicator ce produce inserarea de spaii ntr-o valoare numeric ncepnd de la semn sau de la caracterul bazei: - internal; d) indicatori pentru afiarea / schimbarea bazei: - showbase (prin activarea sa se determin afiarea bazei numrului); - oct (prin activarea sa se determin afiarea ieirii n octal); - hex (prin activarea sa se determin afiarea ieirii n hexazecimal); - dec (prin activarea sa se determin afiarea ieirii n zecimal); n mod implicit, ieirea se afieaz n zecimal. e) indicatori pentru afiarea semnului: - showpos (prin activarea sa se determin afiarea semnului + naintea valorilor pozitive); f) indicatori pentru afiarea ieirii n virgul flotant: - showpoint (prin activarea sa se determin afiarea, la ieirea flotant, a punctului zecimal i a zerourilor finale); scientific (prin activarea sa se determin afiarea ieirii n notaie tiinific);

138

n notaia tiinific, afiarea se face cu litere mici: e, x (exponent, baz hexazecimal) etc. - uppercase (prin activarea sa se determin afiarea ieirii cu litere mari: E,X ). - fixed (prin activarea sa se determin afiarea ieirii flotante n mod normal, rezervnd, n mod implicit ase poziii pentru partea zecimal). g) indicator pentru golirea sistemului de intrare / ieire din C++ dup fiecare operaie de ieire: - unitbuf;

Activarea indicatorilor de format se realizeaz cu ajutorul funciei setf( ), care este o funcie membr a clasei ios. long setf(long indicatori);

Aceast funcie activeaz doar indicatorii care corespund parametrilor ei, ceilali, dac exist, rmn nemodificai. Funcia returneaz valorile precedente ale indicatorului de format. Exemplu: # include <iostream.h> void main ( ){ cout.setf (ios::oct); cout.setf (ios::showbase); cout<<2000; // precizai afiarea! }; Acelai lucru se obine dac lum: cout.setf (ios::showbase | ios::oct); // se folosete operatorul or. Toi indicatorii de format sunt definii n interiorul clasei ios. Accesul la valorile lor este permis prin construcia: ios::id_indicator

Dezactivarea indicatorilor de format se face cu ajutorul funciei unsetf( ), care este tot o funcie membr a clasei ios. long unsetf(long indicatori);

Aceast funcie este util n tergerea a unul sau mai muli indicatori de format corespunztori parametrilor ei. Funcia returneaz starea anterioar a indicatorilor de format. Exemplu: # include<iostream.h> void main( ){ cout.setf(ios::hex| ios::oct); cout<<199; // se va afia c7 cout.unsetf(ios::hex); cout<<\n<<199; // se va afisa 307 }

Ca orice funcie membr, funcia setf( ) se poate suprancrca. long setf(long ind_1, long ind_2);

Efectul este urmtorul: - se dezactiveaz indicatorii de format precizai n ind_2; - sunt afectai doar indicatorii de format precizai n ind_2 n funcie de ind_1 (dac ind_1 mai conine i ali indicatori care nu exist n ind_2, acetia nu vor fi modificai). - funcia returneaz starea anterioar a indicatorului de format. Exemplu: # include<iostream.h> void mai( ){ cout.setf(ios::showbase| ios::oct); cout<<1000; // se afieaz 01750

139

cout.setf(ios::dec,ios::oct | ios::dec); cout<<\n<<1000; // se activeaz dec i se afieaz 1000 }; Se poate face referire la oricare din cmpurile oct, dec, hex, prin ios::basefield. Se poate referi oricare din cmpurile left, right, internal, prin ios::adjustfield. Se poate referi oricare din cmpurile scientific, fixed, prin ios::floatfield. Exemplu: # include<iostream.h> void mai( ){ cout.setf(ios::showbase| ios::oct); cout<<1000; // se afieaz 01750 cout.setf(ios::dec,ios::basefield); cout<<\n<<1000; // se afieaz 1000 };

Examinarea strii curente a indicatorilor de format, fr a modifica valoarea lor, se poate face cu ajutorul funciei flags( ). long flags( ); Exemplu: # include<iostream.h> void showflags( ); void main( ){ showflags( ); // se arata starea implicta a indicatorilor cout.setf(ios::left|ios::right|ios::showpoint); showflags( ); } void showflags( ){ long f1,f2; int k; char tab[5][8]={ "left", "right", "dec", "oct", "hex"}; f1=cout.flags(); // starea indicatorilor de format for(f2=1,k=0;f2<=0x10;f2=f2<<1,k++) if(f2&f1)cout<<tab[k]<<" este activat\n"; else cout<<tab[k]<<" este dezactivat\n"; cout<<"\n"; }

Ieirea programului: left este activat right este dezactivat dec este dezactivat oct este dezactivat hex este dezactivat left este activat right este activat dec este activat oct este dezactivat hex este dezactivat

140

Activarea tuturor indicatorilor de format asociai unui stream se realizeaz prin: long flags(long lf);

Sunt afectai toi indicatorii de format asociai streamului respectiv, deoarece n variabila ce reine aceti indicatori se copiaz structura de bii din lf. Funcia returneaz starea anterioar. n clasa ios exist trei funcii membre care activeaz parametri pentru format: int width(int dc ); Prin aceast funcie se specific o dimensiune minim (dc) a cmpului n care se va afia o ieire, solicitat de unele implementri nainte de ieire. Ea returneaz dimensiunea anterioar a lui. Odat specificat aceast dimensiune minim a cmpului de afiare, valorile, care urmeaz a fi afiate, nu vor fi trunchiate, cmpul extinzndu-se pn la dimensiunea necesar. n mod implicit, se respect dimensiunea dat de numrul caracterelor componente ale acelei ieiri. Cnd se solicit o anumit precizie naintea unei ieiri ce reprezint o valoare flotant, se poate utiliza funcia: int precision (int pr); Precizia este indicat de pr, iar funcia returneaz valoarea precedent. n mod implicit, precizia este de 6 cifre. n mod implicit, un cmp la ieire este completat, pn la dimensiunea precizat, cu spaii. Dac se dorete o umplere cu alt gen de caractere, se va utiliza funcia: char fill (char ch);

Caracterul de umplere este ch, iar funcia returneaz caracterul anterior. Exemplu: # include<iostream.h> void main(){ cout<<3.14562894<<\n;// afieaz 3.14562 (afiare implicit) cout.precision(5); cout.width(10); cout<<3.14562894<<"\n"; //afiseaz 3.1456 (se rotunjete, dac este cazul, cf.preciziei) cout.fill('#'); cout.width(10); cout<<"Sesiunea de examene!"<<"\n";// sirul nu se trunchiaza! Cmpul se extinde. cout.width(10); cout<<"Sesiunea"<<"\n"; cout.width(10);// afiseaz ##Sesiunea (aliniere implicit la dr.) cout.setf(ios::left); cout<<3.14562894;// afiseaz 3.1456#### (se umple pn la 10 caractere cu aliniere la //stnga) }

O alt posibilitate, prin care se pot modifica parametrii de formatare ai unui stream, const n folosirea unor funcii speciale, care se includ n expresii de intrare / ieire, numite manipulatori. Un avantaj n utilizarea manipulatorilor, spre deosebire de indicatorii de formatare, const ntro anume compactificare n scriere, n sensul c este permis o nlnuire a mai multor operatori << cu formate diferite. Se cunoate faptul, c utilizarea bufferelor de intrare / ieire presupune folosirea unor blocuri de memorie ca zone de depozitare temporar a octeilor citii dintr-un flux sau scrii ntr-un flux. Manipulatorii acioneaz asupra unor astfel de buffere n sensul, c ei pot fora golirea complet a unui buffer, pot obliga afiarea coninutului fluxului cout nainte de umplerea bufferului etc.

141

Manipulatorii sunt declarai n iostream.h. Pentru a utiliza acei manipulatori, care folosesc parametri, se va include fiierul iomanip.h. S punem n eviden manipulatorii disponibili n iostream. Manipulatori Exemplu cout<<dec<<iv; cin>>dec>>iv; cout<<endl; cout<<ends; Efect Intrare/ieire n zecimal Trimite o nou linie n ostream i golete bufferul Insereaz un caracter nul ntr-un flux (ieire) Golete bufferul fluxului ostream (ieire) Intrare/ieire n octal Intrare/ieire n hexazecimal Elimin spaiile libere din fluxul de intrare Dezactiveaz indicatorii de format din lf Stabilete baza de conversie la I/O la ntregi (0(baza implicit),8,10,16) Stabilete caracterul de umplere ch a cmpului cf. dimensiunii date (I/O) Activeaz indicatorii de format din lf (I/O) Stabilete precizia pr la datele n virgul mobil (I/O) Stabilete dimensiunea w unui cmp

dec endl ends flush oct hex ws resetiosflags(long lf)

setbase(int baza) setfill(int ch) setiosflags(long lf)

setprecision(int pr) setw(int w) Exemplu:

cout<<flush; cout<<oct<<io; cin>>oct>>io; cout<<hex<ih; cin>>hex>>ih; cin>>ws; cout<<resetiosflags (ios::oct); cin>>resetiosflags (ios::hex); cout<<setbase(16); cin>>setbase(8); cout<<setfill(*); cin>>setfill( ) cout<<setiosflags (ios::dec); cin>>setiosflags (ios::oct); cout<<setprecision(5); cin>>setprecision(10); cout<<setw(5)<<v; cin>>setw(10)>>b;

# include<iostream.h> # include<iomanip.h> void main( ){ int k=900; cout<<"Utilizarea manipulatorilor"<<"\n"; cout<<k<<"\n"; cout<<"Scrie numarul in octal"<<"\n"; cout<<oct<<k<<endl; cout<<"Scrie numarul in hexazecimal"<<"\n"; cout<<hex<<k<<endl; // Se seteaza dimensiunea campului si se umple cu '*'cf. alinierii cout<<setfill('*'); cout<<setw(5)<<oct<<k<<endl; cout<<setw(5)<<hex<<k<<endl; cout<<setiosflags(ios::left); cout<<setw(5)<<oct<<k<<endl; cout<<setw(5)<<hex<<k<<endl; }

142

Cnd ntr-un program se ntlnete, de mai multe ori, aceeai secven de operaii de intrare/ieire, se pot defini funcii de manipulare proprii. a) Crearea manipulatorilor fr parametri: //funcie de manipulare a ieirii fr parametri ostream&id_manip(ostream&str){ //........ return str; }
-

Exemplu: # include<iostream.h> # include<iomanip.h> //Utilizarea unui manipulator de iesire ostream&scrie_octal(ostream&str) { str.setf(ios::showbase); str.setf(ios::oct); return str; } void main( ){ int k=900; cout<<k<<"...."<<scrie_octal<<setw<<k; }

id_manip este identificatorul manipulatorului; se returneaz o referin la un stream de tipul ostream; cnd manipulatorul este introdus ntr-o operaie de ieire nu are parametru;

// funcii de manipulare a intrrii, fr parametri istream&id_manip(istream&str) { //..................... return str; }

Exemplu: # include<iostream.h> # include<string.h> // crearea unui manipulator de intrare istream&anunt(istream&str) { cout<<'\t'; cout<<"Incepe anul universitar!\n"; cout<<"Precizati data calendaristica!\n"; return str; } void main ( ){ char dat[15]; cin>>dat; while(strcmp(dat,"1.oct.1999")){

143

cout<<"Anunt incorect\n\n"; cin>>anunt>>dat; }; cout<<"Data corecta\n"; }

Exist posibilitatea de a crea i manipulatori cu parametri. Acetia ns sunt mai greu de intuit i n acelai timp, metoda de creare a lor, depinde de compilator. De aceea, astfel de manipulatori se utilizeaz cu clase generice (template). Este important ca manipulatorul s returneze un stream pentru a putea fi folosit ntr-o secven de operaii de intrare/ieire. Tematica propus

1. Explicai urmtoarea secven de program: ................................................. double x=199.2348; cout.fill(----); cout.width(12); cout.setf(ios::left,ios::adjustfield); cout<<x<<\n; cout.fill(-->); cout.width(18); cout.setf(ios::right,ios::adjustfield); cout<<x<<\n; ........................................................
2. 3. 4.

S se scrie cte un program n care s se foloseasc: basefield / floatfield. S se scrie cte un program n care s se foloseasc: long flags(long ...); S se exemplifice, n cadrul unor programe, utilizarea funciilor width( ), precision( ), fill( ).

5. S se scrie programe n care s se foloseasc manipulatorii care au fost precizai.

144

Evaluare