Lucrarea nr



Yüklə 0,56 Mb.
səhifə20/20
tarix17.01.2019
ölçüsü0,56 Mb.
#98835
1   ...   12   13   14   15   16   17   18   19   20

10.5Probleme propuse


Problema 1. Se va defini operatorul + ca funcţie membră a clasei Line.
Problema 2. Se va defini operatorul * (de compunere a funcţiilor), ca funcţie globală.

11Prelucrarea fişierelor în limbajul C++

Limbajul C++ defineşte clasele istream şi ostream pentru operaţii de intrare şi ieşire cu fişierele standard, tastatura şi ecranul. Obiectul cin este o instanţă a clasei istream, iar cout o instanţă a clasei ostream. Pentru lucrul cu fişiere de date limbajul C++ defineşte următoarele clase



  • ofstream pentru operaţii de scriere de fişiere

  • ifstream pentru operaţii de citire din fişiere

  • fstream pentru operaţii de citire şi scriere a fişierelor

Aceste clase moştenesc din clasele istream şi ostream. Definiţiile acestor clase se găsesc în biblioteca . O serie de constante utilizate de aceste clase sunt definite în clasa ios. Pentru prelucrarea unui fişier se crează un obiect instanţă a uneia din clasele de mai sus care este denumit stream.

  • clasele definesc un constructor fără parametri.

Funcţiile membre importante ale claselor sunt

  • funcţia open() cu prototipul

open(char * filename, int mode);

asociază obiectul cu fişierul. Parametrul filename este un şir de caractere cu numele fişierului. Al doilea parametru este opţional şi dă modul de deschidere. El poate avea valorile

ios::in - deschidere în citire

ios::out – deschidere în scriere

ios::binary – fişier binary

Aceşti parametri se pot combina folosind operatorul | . De exemplu, pentru un fişier binar deschis în scriere vom avea

ios::binary | ios:out

iar pentru deschiderea unui fişier binar în citire

ios::binary | ios::în

Acest al doilea parametru este opţional pentru obiecte de tipul ifstream şi ofstream, care sunt automat deschise în citire şi respectiv scriere.



  • clasele definesc şi un constructor cu parametrii funcţiei open(). Acest constructor crează un obiect şi apoi deschide fişierul.

  • funcţia

void close();

închide un fişier.



  • funcţia

bool eof();

are valoarea adevărat dacă s-a detectat sfârşitul fişierului



  • funcţia

bool is_open();

are valoarea adevărat dacă fişierul este deschis.



11.1 Fişiere text


Există două tipuri de operaţii intrare/ ieşire pentru fişiere tip text

  • funcţii pentru intrări / ieşiri cu format

  • funcţii ce scriu / citesc caractere


Funcţii intrare / ieşire cu format

Fişierele tip text se prelucrează în acelaşi mod ca fişierele standard de intrare şi ieşire, cin şi cout. Operatorii de citire şi scriere sunt >> şi <<.



Funcţii intrare / ieşire tip caracter

Clasele istream şi ifstream au următoarele funcţii membre pentru citirea caracterelor. Funcţia

get(char&);

citeşte un character.

Funcţia

getline(char * bloc, int size);



citeşte cel mult size caractere în vectorul bloc.

Funcţia clasei istream

getline(char * bloc, int size, char delim);

citeşte cel mult size caractere în vectorul bloc sau până la întâlnirea caracterului delim.

Funcţia globală

istream& getline(istream& file, string str, char delim) ;

citeşte caractere din obiectul file de tip istream în obiectul str de tip string până la întâlnirea caracterului delim. Valoarea implicită a caracterului delim este ‘\n’, în care caz funcţia are forma

istream& getline(istream& file, string str);

Clasele ostream şi ofstream au funcţia membră

put(char);

ce scrie un caracter.
Probleme rezolvate

Problema 1. Să se scrie un program care să calculeze valoarea unei expresii într-un anumit număr de puncte. Rezultatele calculelor se vor scrie într-un fişier text după care acest fişier va fi citit şi afişat pe ecran. Programul de rezolvare a problemei este cel de mai jos.
# include

# include

# include

using namespace std;

int main()

{

char * filename = "rez.txt";



ofstream fil1;

char separator='\t';

fil1.open(filename);

if(!fil1.is_open())

{ cout << " Nu se poate crea fisierul " << filename << endl;

return 0;

}

// calculeaza expresia



double x, e;

for(int i = 0; i < 11; i++)

{

x = i * 0.2;



e = (cos(x) * cos(x) + x) / (1.0 + fabs(x)) + sin(x);

fil1 << x << " " << e << endl;

}

fil1.close();



// citeste fisierul creat si afisaza rezulatele

ifstream fil2;

fil2.open(filename);

if(!fil2.is_open())

{ cout << " nu se poate deschide fisierul " << filename << endl;

return 0; }

cout << "x" << '\t' << "e" << endl;

fil2 >> x >> e;

while(!fil2.eof())

{ cout << x << separator << e << endl;

fil2 >> x >> e; }

fil2.close();

return 0;

}
Rezultatele rulării programului sunt cele de mai jos.




Problema 2. Să se facă un program care să copieze un fişier text. Programul va citi de la tastatură numele fişierului iniţial şi al noului fişier. Copierea se va face citind câte un octet din primul fişier şi scriindu-l în al doilea fişier. Se vor număra şi afişa octeţii citiţi. Programul de rezolvare a problemei este cel de mai jos.

# include

# include

using namespace std;

int main()

{

char filename [24];



cout << “Introduceti numele fisierului de copiat” << endl;

cin >> filename;

ifstream fila(filename);

if(!fila.is_open())

{

cout << endl << “Fisierul “ << filename << “ nu exista “ << endl;



return 0;

}

cout << endl << “Introduceti numele noului fisier” << endl;



cin >> filename;

ofstream filb(filename);

if(!filb.is_open())

{

cout << “Fisierul “ << filename << “ nu se poate crea” << endl;



return 0;

}

char car;



int nl = 0;

fila.get(car);

while(!fila.eof())

{

filb.put(car);



nl++;

fila.get(car);

}

fila.close();



filb.close();

cout << "lungimea fisierului " << nl << " caractere" << endl;

return 0;

}
Rezultatele rulării programului pentru un exemplu concret sunt cele de mai jos.





11.2Fişiere binare


Scrierea şi citirea datelor din fişierele binare se face cu funcţiile

write(char * block, int size);

read(char * block, int size);

Primul parametru este adresa unui vector de caractere de unde sunt scrise datele sau unde sunt citite datele. Al doilea parametru dă numărul de caractere de citit sau de scris.

Fişierele au indicatori interni care dau adresa următorului octet de citit sau de scris. Valoarea acestor indicatori este dată de funcţiile

tellg();

pentru indicatorul următorului octet de citit şi

tellp();


pentru indicatorul următorului octet de scris.

Indicatorii de poziţie sunt modificaţi de funcţiile

seekg(int offset, int direction);

pentru indicatorul de citire şi respectiv

seekp(int offset, int direction);

pentru indicatorul de scriere. Parametrul offset dă valoarea cu care se modifică indicatorul. Parametrul direction are valorile

ios::beg – relativă la începutul fişierului

ios::end – relativă la sfarşitul fişierului

ios::cur – relativă la poziţia curentă
Probleme rezolvate

Problema 1. Se va crea un fişier binar cu 10 blocuri cu şiruri de 10 caractere. Se va citi apoi fişierul şi se va afişa pe ecran. Programul de rezolvare a problemei este cel de mai jos.

# include

# include

using namespace std;

int main()

{

char filename[] = “fis.txt”;



char x[11];

ofstream fila;

// creaza fisierul

fila.open(filename, ios::out | ios::binary);

if(!fila.is_open())

{

cout << “ Nu se poate crea fisierul “ << filename << endl;



return 0;

}

for(int i = 0; i < 10; i++) {



for(int j = 0; j < 10; j++)

x[j] = ‘0’ + i;

x[10] = 0;

fila.write(x, 11);

}

fila.close();



ifstream filb;

// citeste si afisaza fisierul

filb.open(filename, ios::binary | ios::in);

if(!filb.is_open())

{

cout << “Nu se poate citi fisierul “ << filename << endl;



return 0;

}

filb.read(x, 11);



while(!filb.eof())

{

cout << x << endl;



filb.read(x, 11);

}

filb.close();



return 0;

}

Rezultatele rulării programului sunt cele de mai jos.





11.3Probleme propuse


Problema 1. Să se facă un program care să calculeze dimensiunea în octeţi a unui fişier text. Lungimea se va calcula citind câte un octet din fişier.

Problema 2. Se va rezolva problema anterioară modificând indicatorul de poziţie al fişierului.

Problema 3. Să se facă un program care să calculeze numărul de linii dintr-un fişier text. Numărul de linii se va calcula citind toate liniile fişierului.

12Biblioteca de şabloane standard




12.1Clase generice


Clasele din biblioteca de şabloane standard sunt clase generice în care tipurile datelor şi funcţiilor sunt parametri. O clasă generică se defineşte cu instrucţiunea template cu forma
template

class nume_clasa

{

// definitia clasei



};
În această definiţie T1, T2, …, Tn sunt tipuri ce se pot utiliza la declararea de obiecte de tipul clasei generice. Un obiect de tipul unei clase generice se declară cu următoarea diagramă sintactică
nume_clasa nume_obiect;
Problema 1. Să definim o clasă generică X ce poate calcula pătratul unui număr întreg sau real. O reprezentare a clasei este cea de mai jos. În această reprezentare tipul T este parametrul clasei X. Definiţia clasei este cea de mai jos.

# include

using namespace std;


template

class X


{

private:


T a;

public:


X(T b) {a = b;}

T square() {return a * a;}

T geta() {return a;}

};
Să definim obiecte de tipul X ce conţin elemente de tip int sau double utilizând clasa generică X. Programul de rezolvare a problemei este cel de mai jos.


int main()

{

// crează un obiect cu şablonul



X n(2);

cout << "patratul valorii" << n.geta() << " este " << n.square() << endl;

// crează un obiect cu şablonul

X d(3.14);

cout << "patratul valorii" << d.geta() << " este " << d.square() << endl;

return 0;

}


12.2Vectori


Clasa generică vector implementează vectori cu elemente de un anumit tip. Un obiect de tip vector are un număr iniţial de componente şi dimensiunea lui creşte dacă este nevoie. Clasa vector are ca parametru tipul componentelor vectorului.

Clasa defineşte următorii constructori



  • constructorul implicit (fără parametri)

vector();

crează un vector vid



vector(vector p);

crează un vector în care copiază elementele vectorului p care este parametru

Fie T tipul componentelor vectorului (parametrul clasei generice). Clasa defineşte următoarele funcţii


  • void push_back(T&); adaugă un element la sfârşitul vectorului

  • void pop_back(); ştrege ultimul element al vectorului

  • int size(); dă numărul de componente ale vectorului

  • bool empty(); are valoarea true dacă vectorul este vid

  • operatorul [] şi funcţia T& at(int) selectează un element al vectorului

  • T& front(); are ca rezultat primul component al vectorului

  • T& back();are ca rezultat ultimul component al vectorului

Menţionăm că un vector poate avea două sau mai multe elemente egale. Clasa vector este definită în biblioteca .
Problema 2. Să creăm şi să listăm un vector cu componente întregi. Programul este următorul.
# include

# include

using namespace std;

int main()

{

// definim un vector cu componente intregi



vector v;

// adauga 4 elemente

v.push_back(12);

v.push_back(-5);

v.push_back(7);

v.push_back(13);

// afiseaza componentele vectorului

int k;


for(k = 0; k < v.size(); k++)

cout << v[k] << endl;

return 0; }

Rezultatele rulării programului sunt cele de mai jos.




12.3Liste


Clasa generică list implementează o listă dublu înlănţuită, adică o listă ce poate fi parcursă în ambele sensuri. Lista poate avea oricâte elemente de acelaşi tip. Prototipul clasei este definit în biblioteca . Clasa defineşte următorii constructori

  • constructorul implicit

list();

defineşte o listă vidă



  • constructorul

list(list p);

crează o listă în care copiază elementele listei p

Fie T tipul elementelor listei. Funcţiile definite de clasa list sunt următoarele.


  • void push_back(T&); adaugă un element la sfârşitul listei

  • void push_front(T&); adaugă un element la începutul listei

  • void pop_front(); şterge primul element din listă

  • void pop_back(); şterge ultimul element din listă

  • T& front(); are ca rezultat primul element din listă

  • T& back(); are ca rezultat ultimul element din listă


Parcurgerea listelor

Pentru parcurgerea componetelor unei liste se pot utiliza iteratori. Un iterator este asemenea unui pointer la un element al listei. O listă poate fi parcursă în sens direct sau în sens invers.


Parcurgerea listelor în ordine directă

Pentru parcurgerea unei liste în ordine directă se utilizează clasa iterator care este o clasă internă a clasei list. Un obiect de tipul acestei clase se defineşte astfel

list::iterator nume_obiect;

Operatorii implementaţi de clasa iterator sunt ++, -- şi *. Pentru parcurgerea directă a listelor clasa list defineşte funcţiile

begin();

end();


ce au ca rezultat un iterator ce indică primul element al listei şi respectiv ultimul element al listei.
Parcurgerea listelor în ordine inversă

Pentru parcurgerea inversă a listelor se utilizează clasa reverse_iterator care este tot o clasă internă a clasei list. Un obiect de tipul acestei clase se defineşte ca

list::reverse_iterator nume_obiect;

Operatorii implementaţi de clasa iterator sunt ++, -- şi *. Clasa list defineşte funcţiile

rbegin();

rend();


ce au ca rezultat un iterator pentru parcurgerea în sens invers a listei ce indică ultimul element al listei şi respectiv primul element al listei.
Sortarea listelor

Pentru sortarea în ordine directă şi inversă a listelor clasa list defineşte funcţiile

void sort();

void reverse();

ce sorteză elementele listei în ordine directă şi inversă.

Problema 3. Vom crea o listă cu elemente întregi, o vom sorta ascendent şi descendent şi vom afişa elementele listei. Programul este următorul.
# include

# include

using namespace std;
int main()

{

list ls;



// adauga elemente la sfarsitul şi inceputul listei

ls.push_back(11);

ls.push_back(7);

ls.push_front(4);

ls.push_front(12);

// parcurgerea listei

cout << "lista initiala\n";

list::iterator iter;

for(iter = ls.begin(); iter != ls.end(); iter++)

cout << *iter << endl;

// sortarea elementelor listei în ordine crescatoare

ls.sort();

// parcurgerea listei sortate

cout << "lista sortata\n";

for(iter = ls.begin(); iter != ls.end(); iter++)

cout << *iter << endl;

// sortarea elementelor liste în ordine descrescatoare

ls.reverse();

// parcurgerea listei sortate

cout << "lista sortata în ordine inversa\n";

for(iter = ls.begin(); iter != ls.end(); iter++)

cout << *iter << endl;

// parcurgerea listei

cout << "parcurgerea listei în ordine inversa\n";

list::reverse_iterator iter1;

for(iter1 = ls.rbegin(); iter1 != ls.rend(); iter1++)

cout << *iter1 << endl;

return 0;

}

Rezultatele rulării programului sunt cele de mai jos.




12.4Numere complexe


Biblioteca de şabloane standard defineşte clasa complex pentru lucrul cu numere complexe. Prototipul acestei clase este definit în biblioteca . Clasa are ca parametru T, tipul double sau float al perechii de numere reale ce definesc numărul complex. Clasa defineşte următorii constructori

  • Constructorul implicit fără parametri

complex();

ce crează numărul complex 0 + i 0



  • Constructorul copiere

complex(const complex&);

Biblioteca defineşte următorii operatori



  • cei patru operatori aritmetici +, - * , /

  • operatorii relaţionali = = şi !=

  • operatorul de scriere <<. Numărul complex u + i v este scris de operatorul << ca

(u, v)

  • operatorul de citire >>. Pentru citirea cu operatorul >> numărul complex u + i v este introdus ca

(u, v)

Clasa defineşte următorii operatori de atribuire



  • =, +=, -=, *= , /=

Biblioteca defineşte următoarele funcţii matematice standard care au ca argumente numere complexe

asin sin exp pow

acos cos log sqrt

atan tan log10

Biblioteca defineşte următoarele funcţii


  • T real();

  • T real(const complex&);

dau partea reală a numărului complex, prima este funcţie membră a clasei

  • T imag();

  • T imag(const complex&);

dau partea imaginară a numărului complex, prima este funcţie membră a clasei

  • complex conj(complex&);

are ca rezultat conjugatul numărului complex

  • T abs(complex&);

dă valoarea absolută (norma) a numărului complex

  • T norm(complex&);

dă pătratul valoarii absolute (normei) a numărului complex

12.5Probleme propuse


Problema 1. Să se definească o listă de şiruri de caractere. Se va parcurge lista în ambele sensuri şi se vor sorta componentele în ordine crescătoare.
Problema 2. Se va crea un vector cu elementele şiruri de caractere. Se vor lista componentele vectorului în ordine directă şi în ordine inversă.
Problema 3. Fie numerele complexe 1.2 + 3i şi -2.1 + 6.3i. Să se facă un program care să calculeze suma, diferenţa, produsul şi câtul numereleor complexe.
Problema 4. Fie functia

Să se calculeze valorile funcţiei pentru s luând valori de la 0i la 100i cu pasul 5i.







Yüklə 0,56 Mb.

Dostları ilə paylaş:
1   ...   12   13   14   15   16   17   18   19   20




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©muhaz.org 2024
rəhbərliyinə müraciət

gir | qeydiyyatdan keç
    Ana səhifə


yükləyin