Documente Academic
Documente Profesional
Documente Cultură
Bibliografie:
Walter Sowitch - Problem Solving with C++
Addison Wedey Publishing Company, 1996
Referinte:
http://www.cs.tuiasi.ro/library
Introducere
#include <iostream.h>
void main
{
int a;
#include <iostream.h>
void main()
{
double b;
Daca apoi, se doreste afisarea a trei zecimale, se face doar setarea cout.precision(3);
In general, cout afiseaza un format asemanator cu cel de intrare.
Ex:
#include <iostream.h>
Deci avem 2 functii ave cu numar diferit de parametri. In acest caz compilatorul o va alege pe cea ce are numarul corect
de parametri.
Inseamna definirea a doua sau mai multe functii cu acelasi nume. Cand supraincarcarea numelui unei functii trebuie sa
aiba numar diferit de parametri formali sau anumiti parametri formali de tipuri diferite. Cand avem un apel de functie
compilatorul foloseste definitia functiei a carei numar si tipuri de parametri formali se potriveste cu argumentele din apelul
functiei.
Folosirea aceluiasi nume pentru a desemna lucruri diferite se numeste polimorfism (termen derivat din cuvinte grecesti ce
inseamna "multe forme"). Supraincarcarea este un exemplu de polimorfism.
Avem 2 cazuri atunci cand apelam una din functii folosind constante:
I. daca apelam functia f cu o constanta de tip intreg atunci compilatorul
va folosi f(int a) ceea ce este corect;
II. daca apelam functia f cu o constanta de tip float atunci compilatorul
va semanala eroarea "Ambiguity between f(int) and f(float)"
#include <iostream.h>
void main()
{
int i = 2, j = 3;
cout << "i = " << i << "; j = " << j << endl;
schimba(i, j);
cout << "i = " << i << "; j = " << j << endl;
schimba(&i, &j);
cout << "i = " << i << "; j = " << j << endl;
}
Un stream (curent,curs) este un flux de caractere (sau alte tipuri de date). Daca fluxul este in program, atunci se cheama
flux de intrare altfel este flux de iesire.
In C++, un flux este un tip special de variabile cunoscut ca obiect. Tipul pentru variabile de flux-fisiere de intrare este
numit ifstream (input file stream), iar pentru iesire ofstream (output file stream).
Ex:
ifstream in_stream;
ofstream out_stream;
Aceste doua clase sunt definite in fisierul header <fstream.h>, fisier ce trebuie inclus cu #include <fstream.h>.
Variabilele de flux trebuie declarate, adica conectate la un fisier. Asta inseamna deschiderea fisierului.
in_stream.open("fis.dat");
int a,b;
in_stream >> a >> b;
ofstream out_stream;
out_stream.open("outfile.dat");
in_stream.close();
out_stream.close();
unde in_stream si out_stream sunt obiecte din clasele ifstream si ofstream, "." este operatorul punct iar close() este o
functie membru din aceste clase.
Ex:
Clasa ifstream are o functie membru numita open si clasa ofstream are de asemeni o functie membru numita open.
Clasa ofstream are de asemeni o functie membru numita precision. (dar clasa ifstream nu are nici o functie membru
numita precision).
In general, un obiect este o variabila care are functii asociate. Aceste functii se numesc functii membru. O clasa este un
tip a carui variabile sunt obiecte. Tipul obiectului determina ce functii membru are obiectul. Apelarea unei functii membru
pentru un obiect se face folosind operatorul "."
Sintaxa:
obiect_apelat.nume_functie_membru(lista_argumente)
Un alt caz de polimorfism este folosirea aceluiasi nume pentru functii membru din clase diferite, cum este cazul lui open.
Exista o functie membru fail care testeaza daca o operatie de flux a esuat sau nu. Aceasta functie membru este valabila
pentru ifstream si ofstream.
Ex:
in_stream.open("fisier.dat");
if ( in_stream.fail() )
{
cout << "Fisier de intrare deschis gresit" << endl;
exit(1);
}
Obs:
Functia exit este caracteristica limbajului C si este definita in
fiserul antet <stdlib.h>
#include <fstream.h>
#include <iostream.h>
#include <stdlib.h>
int main()
{
// Acest program citeste doua nume de fisiere unul de intrare,
// unul de iesire. Apoi citim din fisierul de intrare trei
// numere intregi, apoi in fisierul de iesire scriem suma lor.
char fis_in[16], fis_out[16];
ifstream in_stream;
ofstream out_stream;
cout << "Dati numele fisierului de intrare.\n";
cin >> fis_in;
in_stream.open(fis_in);
if (in_stream.fail())
{
cout << "Eroare la deschidere fisier de intrare.\n";
exit(1);
}
cout << "Dati numele fisierului de iesire.\n";
cin >> fis_out;
out_stream.open(fis_out);
if (out_stream.fail())
{
cout << "Eroare la deschidere fisier de iesire.\n";
exit(1);
}
int a, b, c;
in_stream >> a >> b >> c;
out_stream << "Suma celor 3 numere este " << a + b + c << endl;
in_stream.close();
out_stream.close();
return 0;
}
out_stream.setf(ios::fixed);
out_stream.setf(ios::showpoint);
out_stream.precision(2);
Ex: cout.unsetf(ios::showpos);
Un manipulator este o functie membru de flux apelata in mod netraditional. Acestia sunt plantati dupa operatorul de
insertie <<. Deocamdata prezentam doar 2 manipulatori: setwidth si setprecision ( manipulatorul setwidth este echivalent
cu functia membru witdh ).
Ex:
cout << "Afisam intregii " << setw(4) << 10
<< setw(5) << 20 << setw(6) << 30;
Ex:
cout.setf(ios::fixed);
cout.setf(ios:showpoint);
cout << "$" << setprecision(2) << 10.3 << endl
setprecision(3) << "$" << 20.5 << endl;
Obs:
Pentru lucrul cu acesti operatori(setw, setprecision) trebuie sa includeti
directiva:
#include <iomanip.h>
Ex:
int main()
{
ifstream fin;
ofstream fout;
fin.open("fis_in.dat");
if (fin.fail())
{
cout << "Deschiderea fisierului de intrare a esuat.\n";
exit(1);
}
fout.open("fis_out.dat");
if (fout.fail())
{
cout << "Deschiderea fisierului de iesire a esuat.\n";
exit(1);
}
afisare_frumoasa(fin, fout, 5, 12);
fin.close();
fout.close();
cout << "Sfarsitul programului.\n";
return 0;
}
double urmator;
while (fisier_urat >> urmator)
{
cout << setw(latime_camp) << urmator << endl;
fisier_frumos << setw(latime_camp) << urmator << endl;
}
}
Functia get permite citirea unui caracter de la intrare si memorarea lui intr-o variabila de tip char. get este o functie
membru pentru fluxul cin si se poate extinde la orice fisier de intrare.
Am vazut ca cin cu operatorul de extractie >> citeste un caracter (sau orice alta intrare). Unele lucruri sunt facute
automat, cum ar fi trecerea peste spatii. Folsind functia membru get, nimic nu se face automat (trecerea peste spatii trebuie
facuta de catre programator).
Ex_1:
char a;
cin.get(a);
Ex_2:
char c1,c2,c3;
cin.get(c1);
cin.get(c2);
cin.get(c3);
La intrare avem: AB
CD, atunci se va unifica astfel: C1='A',C2='B',C3='\n'
Alt exemplu:
'a' - un caracter, "a" = 'a' '\0' - un sir de 2 caractere
Flux_de_intrare.get(variabila_de_tip_char)
Obs:
Flux_de_intrare este obiect al clasei ifstream.
in cazul lui cin, trebuie sa adaugam fisierul antet <iostream.h>
daca este alt fisier (diferit de cel standard) atunci adaugam <fstream.h>
Functia membru put este valabila pentru fluxuri de iesire. Ea are un argument care este o expresie de tip char. Cand
functia este apelata,
valoarea argumentului este trimisa catre fluxul de iesire.
Sintaxa: Flux_de_iesire.put(Expresie_caracter);
Ex: cout.put(simbol_urmator);
cout.put('a');
Uneori dorim sa stim urmatorul caracter dintr-un flux de intrare. Insa folosind get, pointerul catre fisier indica deja
urmatorul caracter. Dorim acum sa punem inapoi caracterul in fluxul de intrare.
Functia putback este un membru pentru orice flux de intrare. Acesta are un argument de tip char si plaseaza valoarea
argumentului inapoi in fluxul de intrare.
Ex: scriem un cod C care citeste caracter cu caracter pana la primul spatiu care este introdus inapoi in fluxul de intrare:
fin.get(a);
while (a != ' ')
{
fout.put(a);
fin.get(a);
}
fin.putback(a);
Obs: fin este un obiect al clasei ifstream iar fout este un obiect al clasei ofstream.
Fiecare flux al unui fisier de intrare are o functie membru eof (end-of-file), folosita pentru determinarea situatiei cand
intreg fisierul a fost citit si nu a mai rama nici o intrare pentru program.
Functia eof nu are argumente, deci daca fluxul de intrare se cheama fin, atunci un apel al functiei eof se scrie:
fin.eof();
Expresia fin.eof() returneaza true daca programul a fost citit (adica s-a trecut de sfarsitul fisierului de intrare), altfel
expresia de mai sus intoarce false.
Ex_1:
if ( ! fin.eof() )
cout << "Nu este sfarsitul fisierului.\n";
else
cout << "Sfarsitul fisierului.\n";
Ex_2:
//presupunem ca fluxul de intrare in_stream este conectat la un fisier
//de intrare. Iata cum putem lista la ecran continutul fisierului.
in_stream.get(next);
while ( ! in_stream.eof() )
{
cout << next;
in_stream.get(next);
}
Functii ( macrouri ) din <ctype.h>: toupper, tolower, isupper, islower, isalpha, isdigit, isspace ( de repetat din C ).
Mostenire
Una din trasaturile cele mai importante ale C++ o reprezinta folosirea claselor derivate. O clasa este derivata din alta
clasa daca clasa derivata se obtine din prima adaugand cateva trasaturi (proprietati).
Ex_1:
Clasa fluxurilor fisierelor de intrare (ifstream) este derivata din clasa tuturor fluxurilor de intrare (istream) prin
adaugarea de functii membru suplimentare cum ar fi open si close. Fluxul cin apartine clasei tuturor fluxurilor de intrare,
dar nu apartine clasei fluxurilor fisierelor de intrare pentru ca cin nu are functiile membru open si close.
Un obiect este o variabila care are functii membru, iar o clasa, este un tip a carui variabile sunt obiecte. Fluxurile ( cum ar
fi cin, cout, fluxuri fisiere de intrare, fluxuri fisiere de iesire) sunt obiecte, deci tipurile fluxurilor (ifstream,ofstream) sunt
clase.
Cin si fluxurile fisiere de intrare sunt fluxuri de intrare. Putem folosi operatorul de extractie >> pe ambele tipuri de
fluxuri. Un flux fisier de intrare poate fi conectat la un fisier folosind functia open, dar nu si cin. Un flux fisier de intrare
este de tip ifstream, iar cin este de tip istream.
Clasele ifstream si istream sunt diferite. Legatura dintre ele este ca ifstream este o clasa derivata a lui istream.
Ex:
Consideram o functie care citeste doi intregi din fluxul de intrare fisier_sursa si afiseaza suma lor la ecran:
nu va functiona deoarece cin nu este de tip ifstream. Deoarece cin este de tip istream, mai scriem inca
o functie numita suma1, in care argumentul este istream& fisier_sursa. Acum apelul suma1(cin); va functiona.
De asemeni, va functiona si apelul suma1(fin). Justificarea este ca ifstream este o clasa derivata a clasei
istream.
Orice flux de tip ifstream este de asemeni de tip istream, deci un parametru formal de tip istream argumentul
folosit in apelul functiei poate fi un flux de intrare conectat la un fisier sau la fluxul cin.
Clasele derivate sunt des folosite pentru mostenire si relatiile dintre functii. Daca clasa B este clasa derivata a clasei A,
atunci clasa B se numeste fiul (copilul) clasei A si clasa A se numeste parintele clasei B. Clasa derivata mosteneste
functiile membru ale clasei parinte.
Ex: am vazut ca orice flux de intrare mosteneste operatorul de extractie << din clasa tuturor functiilor.
1. Scrieti un program C++ ce foloseste stream-uri astfel incat sa inlocuiti fiecare caracter dintr-un fisier de intrare cu un sir
de caractere in fisierul fisierul de iesire.
2. Scrieti un program C++ care citeste dintr-un fisier inregistrari de forma (cate o inregistrare pe linie):
string double
si creeaza un alt fisier care contine informatiile din primul fisier + media celor 3 note pe respectiva linie ( la sfarsit ).
3. Scrieti un program C++ care citeste numere sortate crescator din doua fisiere si scrie in al treilea fisier reuniunea lor
sortata crescator.
ATENTIE ! Se utilizeaza spatiu suplimentar de memorie constant.
4. Scrieti un program care citeste un fisier C++ inlocuind versiunile incorecte cin << si cout >> cu versiunile corecte cin
>> si cout << .
ATENTIE! Intre cin si << pot fi oricate spatii ( inclusiv 0 ).