Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
POO - Curs Doc-1.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
868.86 Кб
Скачать

8) Aceste mesaje apar după ce se termină lucrul programului.

Destructorii se apelează automat de către sistem pentru

fiecare obiect creat din program, în ordine inversă:

Obiectul (Ion Padure) a fost distrus.

Obiectul (Necunoscut) a fost distrus.

Obiectul (Dan Balan) a fost distrus.

Obiectul (Ion Padure) a fost distrus.

Obiectul (Petru Moraru) a fost distrus.

§4. Operaţii de intrare/ieşire a informaţiei.

În limbajul C++ sunt admise toate operaţiile de intrare/ieşire caracteristice limbajului C. Suplimentar, în limbajul C++ au fost definite operaţii noi de intrare/ieşire care sunt create în stilul programării orientate pe obiecte. Au fost create o serie de clase orientate la intrarea/ieşirea informaţiei. În baza acestor clase sunt definite obiecte care, la rândul său, includ operaţii ce permit intrarea/ieşirea informaţiei. O astfel de abordare şi stil de realizare, are avantajul de a putea fi extinsă pentru necesităţile unei clase concrete.

Pentru ieşirea sau afişarea informaţiei, este definit obiectul cout, iar pentru intrarea sau citirea informaţiei, este definit obiectul cin. Pentru afişarea mesajelor despre erori sunt definite obiectele cerr şi clog. Fiecare dintre obiecte poate utiliza atât operatorii, cât şi funcţiile caracteristice clasei din care este instanţiat el. În contextul obiectelor cout, cerr şi clog este utilizat operatorul <<, numit operator de inserţie sau scriere, iar în contextul obiectului cin este utilizat operatorul >>, numit operator de extragere sau citire. O formă generală de utilizare a operatorului << ar fi următoarea:

cout<<exp1<<exp2<<...<<expN;

unde exp1, exp2, …, expN (N1) sunt expresiile a căror valori sunt afişate. Expresiile concatenate într-o expresie lungă pot fi afişate separat:

cout<<exp1;

cout<<exp2;

. . .

cout<<expN;

Un exemplu de afişare a valorilor unor variabile:

int i=-27;

char c=’a’;

char s[]=”Un sir”;

long l=100000;

cout<<i;

cout<<c;

cout<<s;

cout<<l;

Rezultatul afişării:

-27aUn sir100000

Desigur că scriind:

cout<<i<<c<<s<<l;

va fi obţinut acelaşi rezultat al afişării.

Pentru operatorul de citire >> este valabilă următoarea formă generală:

cin>>var1>>var2>>...>>varN;

unde var1, var2, …, varN (N1) sunt variabilele în care sunt citite valori.

Acelaşi lucru poate fi realizat şi în expresii separate:

cin>>var1;

cin>>var2;

. . .

cin>>varN;

Un exemplu de utilizare a obiectului cin:

unsigned u;

float f;

long double ld;

cin >> u >> f >> ld;

Delimitatori ai valorilor introduse sunt spaţiile albe ’ ’, ’\t’, ’\n’.

Pentru a putea utiliza în programe obiectele şi operatorii respectivi, este inclus fişierul antet <iostream.h>, unde sunt efectuate descrierile necesare referitoare la aceste obiecte.

Obiectele cout şi cin permit, de asemenea, şi operaţii de formatare care sunt realizate prin intermediul unor construcţii numite manipulatori. Un manipulator schimbă starea fluxului pregătindu-l pentru careva operaţii de formatare. Pentru a putea folosi manipulatorii, este necesară includerea fişierului antet <iomanip.h>. În caz general, un manipulator acţionează asupra fluxului, acţionând asupra obiectului implicat în operaţiile de intrare/ieşire prin intermediul operatorului corespunzător:

cout << manipulator[ << . . .];

sau

cin >> manipulator[ >> . . .];

unde punctele de suspensie ”. . .” înseamnă o posibilă continuare a construcţiei.

Fluxul de intrare are mai puţini manipulatori decât cel de ieşire. Pentru ignorarea spaţiilor albe la citirea informaţiei, este utilizat manipulatorul ws. În exemplul următor:

double d;

cin >> ws >> d;

sunt ignorate spaţiile albe în procesul citirii valorii în variabila d.

În continuare, vor fi caracterizaţi manipulatorii fluxului de ieşire. Pentru a trece din rând nou la ieşirea (afişarea) informaţiei, este utilizat manipulatorul endl. Din exemplul ce urmează se poate vedea că acest manipulator poate fi modelat afişând secvenţa de dirijare ’\n’:

int i=10;

float f=1.2;

char s[]=”Un exemplu”, c=’A’;

cout<<i<<endl<<f<<endl<<c<<”\n”<<s<<endl;

Rezultatul afişării:

10

1.2

A

Un exemplu

În continuare urmează un grup de manipulatori care se referă doar la tipuri de date întregi:

  • oct permite fixarea sistemului de numeraţie octal;

  • dec permite fixarea sistemului de numeraţie zecimal;

  • hex permite fixarea sistemului de numeraţie hexazecimal.

Oricare dintre aceşti manipulatori îşi fixează acţiunea până la anularea ei de un alt manipulator din acest grup.

int i=10;

cout<<i<<” ”<<oct<<i<<” ”<<hex<<i<<” ”<<dec<<i<<endl;

Rezultatul afişării:

10 12 a 10

Manipulatorii descrişi anterior sunt manipulatori ne-parametrizaţi. Există o serie de manipulatori parametrizaţi, a căror descriere urmează în continuare. Ei sunt realizaţi sub formă de funcţii, deci, modul lor de utilizare este asemănător cu apelarea unor funcţii.

Un manipulator a cărui acţiune este echivalentă cu acţiunea manipulatorilor oct, dec, hex este manipulatorul setbase. Modul lui de utilizare este

setbase(baza)

unde parametrul baza poate lua valorile 8, 10 sau 16, permiţând respectiv fixarea sistemului de numeraţie octal, zecimal sau hexazecimal. Va fi rescris exemplul anterior utilizând setbase:

int i=10;

cout<<i<<” ”<<setbase(8)<<i<<” ”<<setbase(16)<<i<<” ”<<setbase(10)<<i<<endl;

Rezultatul afişării:

10 12 a 10

Dacă este necesară fixarea lăţimii câmpului de afişare, este utilizat manipulatorul setw. Forma generală este:

setw(latime)

unde parametrul latime reprezintă o expresie întreagă care dictează lăţimea câmpului de afişare. Lăţimea câmpului este fixată doar pentru o singură afişare, după care se revine la valoarea implicită egală cu unu.

Un exemplu de utilizare a acestui manipulator:

int i=10, lat=5;

char c=’A’;

cout<<setw(3)<<i<<setw(lat)<<c<<endl;

Rezultatul afişării (fiecare celulă reprezintă o poziţie pe ecran):

1

0

A

Din exemplul precedent se vede că dacă valoarea afişată are mai puţine simboluri decât numărul de poziţii ale câmpului de afişare, atunci poziţiile rămase sunt completate cu spaţii ’ ’. Acesta este caracterul implicit de completare. Însă este posibilă fixarea altui caracter de completare, utilizând manipulatorul setfill. Forma generală este:

setfill(caracter_completare)

unde parametrul caracter_completare reprezintă o expresie, care oferă caracterul de completare. Caracterul de completare este fixat până la o nouă fixare. În continuare este re-scris exemplul precedent, utilizând şi manipulatorul setfill:

int i=10, lat=5;

char c=’A’;

cout<<setfill(’.’);

cout<<setw(3)<<i<<setw(lat)<<c<<endl;

Rezultatul afişării:

.

1

0

.

.

.

.

A

Pentru a fixa exactitatea de afişare a valorilor cu virgulă mobilă este utilizat manipulatorul setprecision. Forma generală de utilizare este următoarea:

setprecision(exactitate)

unde parametrul exactitate este o expresie întreagă, care dictează numărul de cifre semnificative după virgulă. Exactitatea este fixată pentru toate afişările, până la o nouă fixare. Dacă parametrul exactitate ia valoarea 0, atunci se revine la exactitatea implicită egală cu 6 cifre după virgulă. Iată un exemplu:

float f=1.2;

double d=-15.4563283432;

int i;

cout << f << ” ” << d << endl;

for(i=0;i<6;i++)

cout<<setprecision(i)<<f<<” ”<<d<<endl;

Rezultatul afişării:

1.2 -15.456328

1.2 -15.456328

1.2 -15.5

1.2 -15.46

1.2 -15.456

1.2 -15.4563

1.2 -15.45633

Un manipulator cu o gamă largă de acţiuni de formatare este manipulatorul setiosflags. Forma generală de aplicare a acestui manipulator este:

setiosflags(fanioane)

unde parametrul fanioane permite fixarea unor proprietăţi, numite fanioane. Fiecare fanion este responsabil de o anumită acţiune. Fanioanele, utilizate cu manipulatorul setiosflags sunt descrise sub formă de enumerare în cadrul clasei ios. De aceea denumirile fanioanelor sunt precedate de denumirea clasei ios şi operatorul rezoluţiei.

Tabelul următor descrie acţiunile, ce ţin de fiecare fanion:

Nr.

Nume fanion

Acţiune caracteristică

1

ios::skipws

ignorarea spaţiilor albe

2

ios::left

alinierea informaţiei în partea stângă a câmpului

3

ios::right

alinierea informaţiei în partea dreaptă a câmpului

4

ios::internal

alinierea informaţiei în ambele părţi dacă este posibilă

5

ios::showpos

forţarea semnului

6

ios::showbase

baza sistemului de numeraţie

7

ios::showpoint

forţarea punctului pentru numerele cu virgulă mobilă

8

ios::fixed

afişarea numerelor reale în format cu punct fix

9

ios::scientific

afişarea numerelor reale în format ştiinţific

10

ios::hex

afişarea numerelor întregi în format hexazecimal

11

ios::oct

afişarea numerelor întregi în format octal

12

ios::dec

afişarea numerelor întregi în format zecimal

13

ios::stdio

golirea fluxul stdout şi stderr

14

ios::uppercase

scrierea numerelor hexazecimale cu litere majuscule

15

ios::unitbuf

golirea tuturor fluxurilor de date dupa citirea datelor

Iată o serie de exemple ce descriu acţiunile manipulatorului setiosflags.

Alinierea stânga sau dreapta:

int i=10;

cout<<setiosflags(ios::left)<<setw(5)<<i

<<setfill(’-’)<<setiosflags(ios::right)

<<setw(5)<<i<<endl;

Rezultatul afişării:

1

0

-

-

-

1

0

Forţarea semnului şi a punctului:

float f=20;

cout<<f<<’ ’<<setiosflags(ios::showpos)<<f<<’ ’

<<setiosflags(ios::showpoint)<<f<<’ ’<<endl;

Rezultatul afişării:

2

0

+

2

0

+

2

0

.

0

0

0

0

0

0

Manipulatorul setiosflags permite combinarea mai multor fanioane concomitent. Pentru aceasta este utilizat operatorul | (SAU). Iată un exemplu:

long l=0x49;

cout << setiosflags(ios::showbase | ios::hex);

cout << setw(6) << l << setiosflags(ios::internal)

<< setw(6) << l << endl;

Rezultatul afişării:

0

x

4

9

0

x

4

9

Pentru a restabili fanioanele la valorile implicite, este utilizat manipulatorul resetiosflags, care acţionează similar cu manipulatorul setiosflags. În exemplul următor este restabilit fanionul ios::showpoint:

double d=-320;

cout <<setiosflags(ios::showpoint) << d << ’ ’

<<resetiosflags(ios::showpoint) << d <<endl;

Rezultatul afişării:

-

3

2

0

.

0

0

0

0

0

0

-

3

2

0

Clasele orientate la intrarea/ieşirea informaţiei au pe lângă operatori şi o serie de funcţii cu acţiuni specifice, utile în procesul de intrare/ieşire a informaţiei. Astfel, funcţiile corespunzătoare pot fi utilizate cu obiectele cout şi cin.

Pentru a citi un caracter din fluxul de intrare, este utilizată funcţia get(). Forma de utilizare este următoarea

cin.get(caracter);

unde parametrul caracter este variabila în care este citită valoarea. De exemplu:

char c;

cin.get(c);

Operatorul de citire >> a obiectului cin nu permite un lucru eficient cu şiruri de caractere. De exemplu, dacă se doreşte a citi numele şi prenumele unei persoane într-o variabilă, atunci o astfel de soluţie

char persoana[100];

cin >> persoana;

nu este corectă, fiindcă în variabila persoana va fi citit doar numele persoanei, prenumele fiind ignorat, fiindcă spaţiul joacă rolul de trecere la prelucrarea următorului câmp de intrare. Pentru a putea citi propoziţii, va fi utilizată funcţia getline(), care are următoarele forme:

getline(char *sir, int lung_max);

getline(char *sir, int lung_max, char caracter_oprire);

unde parametrul sir este şirul în care se citeşte, parametrul lung_max este lungimea maximală a informaţiei citite, iar parametrul caracter_oprire reprezintă caracterul la întâlnirea căruia se va întrerupe procesul de citire. Pentru prima variantă a funcţiei, caracterul de oprire este ’\n’, generat de tasta Enter. Astfel sarcina propusă anterior poate fi soluţionată aşa:

char persoana[100];

cin.getline(persoana, sizeof(persoana));

Dacă este necesar de a afla câte caractere au fost citite în fluxul neformatat este aplicată funcţia gcount().

char nuA[50];

int i;

cin.getline(nuA, sizeof(nuA), ’a’);

i=gcount();

cout << i << endl;

Fragmentul anterior afişează câte simboluri au fost citite în variabila nuA până la întâlnirea primului simbol ’a’.

Desigur că şi obiectul cout are o serie de funcţii utile. Funcţia width() are două variante. Una permite citirea lăţimii curente, iar alta permite fixarea lăţimii curente. Iată forma lor generală:

int width();

şi

int width(latime);

unde latime este expresia a cărei valoare va fi luată drept bază pentru fixarea lăţimii câmpului de afişare. De exemplu:

float f=10.25;

cout.width(8);

cout<<f<<endl;

Rezultatul afişării:

1

0

.

2

5

Două forme similare are şi funcţia precision(), care se referă la exactitatea de afişare a valorilor cu virgulă mobilă: varianta fără parametri returnează exactitatea curentă, iar varianta cu parametru fixează exactitatea necesară. De exemplu

double d=-114.361782;

cout.precision(4);

cout<<d<<endl;

Rezultatul afişării:

-

1

1

4

.

3

6

1

8

Pentru a determina caracterul de umplere a poziţiilor ne-acoperite de simbolurile valorii afişate poate fi utilizată funcţia fill() fără parametri. De exemplu, fragmentul ce urmează:

char cu;

cu=cout.fill();

cout << cu << endl;

va afişa caracterul de umplere curent cu, determinat utilizând funcţia fill(). Pentru a fixa caracterul de umplere, este utilizată, de asemenea, funcţia fill(caracter_umplere) cu parametri, având ca parametru o expresie ce oferă caracterul de umplere. De exemplu, în cele ce urmează va fi fixat caracterul de umplere ’*’.

long l=-249793;

cout.fill(’*’);

cout.width(10);

cout<<l<<endl;

Rezultatul afişării:

*

*

*

-

2

4

9

7

9

3

Pentru a putea lucra cu fanioanele caracterizate anterior, poate fi utilizată funcţia flags(), care are o variantă fără parametri şi o variantă cu parametri.

int fnv = cout.flags();

int fn = 0x1234;

cout.flags(fn);

cout << 239 << endl;

cout.flags(fnv);

În acest exemplu sunt utilizate ambele variante, care permit fixarea valorii vechi a fanioanelor şi revenirea la această valoare după afişarea valorii întregi 239.

Exemplu. De alcătuit un program în care este modelat un cuprins de carte.

#include<iostream.h>

#include<iomanip.h>

#include<string.h>

#define latimePagina 65

void main()

{

char *paragrafe[]={”Cuprins”,”Introducere”,

”Clase si obiecte”,

”Constructor.Destructor”};

int pagini[]={3,10,12};

int i, lung;

lung=strlen(paragrafe[0]);

cout << setw((latimePagina+lung)/2); //Centrare

cout << paragrafe[0] << endl; //Cuprins

cout << setfill(’.’);

for(i=0; i<3; i++)

{

cout << paragrafe[i+1];

lung=strlen(paragrafe[i+1]);

cout << setw(latimePagina-lung);

cout << pagini[i] << endl;

}

}

Rezultatul afişării:

Cuprins

Introducere.....................................................3

Clase si obiecte...............................................10

Constructor.Destructor.........................................12

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]