Sunteți pe pagina 1din 11

4. Intrrile n program.

Scrierea aplicaiilor
Un program are nevoie de date pentru a opera. Pn acum am scris programe n care valorile datelor se gsesc chiar n program, n constante simbolice sau literale. Dac dorim s modificm o dat, trebuie s facem o mic modificare n program, s l recompilm i s l executm din nou. n acest capitol vom vedea cum putem introduce date n program chiar n timpul rulrii lui. Odat ce am aflat cum s introducem date n program, s procesm datele i s afim rezultatele, putem s ne gndim la scrierea unor programe mai complicate. Pentru aceasta avem nevoie de o abordare ceva mai organizat. n finalul capitolului vom discuta despre descompunerea n module i despre programarea orientat pe obiecte.

4.1

Transmiterea datelor ctre programe

Unul dintre marile avantaje ale calculatorului este c un program poate fi folosit cu diverse seturi de date. Pentru aceasta trebuie s separm datele de program pn n momentul execuiei. Anumite instruciuni din program copiaz valori n variabilele din program. Dup stocarea acestor valori n variabile, programul poate s le foloseasc n calcule. Procesul de plasare a unor valori dintr-o mulime de date n variabile din program se numete intrare (input). ntr-o terminologie mai larg, calculatorul se spune c citete date din exterior n variabile. Datele pot proveni dintr-un fiier, de la tastatur etc. Dispozitivul standard de intrare este tastatura.

Stream-uri de intrare i operatorul de extracie >>


n C++, conceptul de stream este esenial. Putem gndi un stream de ieire ca pe o secven infinit de date care circul dinspre program nspre un dispozitiv de ieire. Un stream de intrare este o secven infinit de caractere care pornete de la un dispozitiv de intrare i este dirijat ctre program. Fiierul header iostream conine, printre altele, definiiile a dou tipuri de date: istream i ostream. Aceste tipuri de date reprezint stream-uri de intrare i stream-uri de ieire. Acest fiier header mai conine dou declaraii care arat aproximativ astfel: istream cin; ostream cout; Cele dou declaraii arat c cin este un obiect de tip istream i cout este un obiect de tip ostream. n mod explicit, cin este asociat cu tastatura, iar cout cu display-ul. Am vzut c trimiterea unor valori ctre cout se face folosind operatorul de inserie <<: cout << 3 * pret; Similar, putem citi date din cin folosind operatorul de extracie >>: cin >> cost; Operatorul de extracie >> are doi operanzi. n stnga se gsete un stream, n cel mai simplu caz cin, iar n dreapta se gsete o variabil avnd un tip predefinit (char, int, float etc.). Putem folosi operatorul de mai multe ori ntr-o instruciune: cin >> lungime >> latime;

Programarea calculatoarelor i limbaje de programare I

fiind echivalent cu: cin >> lungime; cin >> latime; Trebuie s fim ateni atunci cnd folosim cei doi operatori, pentru c cin poate fi folosit doar n combinaie cu >>, iar cout doar cu <<. Dac ntr-o instruciune de afiare putem folosi constante, variabile i chiar expresii foarte complicate, ntr-o instruciune de intrare nu putem folosi dect nume de variabile. Aceasta pentru c o instruciune de intrare trebuie s precizeze clar unde se stocheaz valoarea unei date de intrare. Doar numele de variabile refer locaii de memorie ale cror valori pot fi modificate n timpul execuiei unui program. Atunci cnd introducem o dat de la tastatur, trebuie s ne asigurm c tipul introdus i cel ateptat de program se potrivesc. Un numr ntreg este forat automat la un numr real. Operaia invers, ns, poate conduce la rezultate eronate. Atunci cnd extrage valori dintr-un stream, operatorul >> ignor orice spaiu de la nceput. De asemenea, ignor caracterul care marcheaz sfritul liniei. Apoi, operatorul >> procedeaz la extragerea valorilor din stream-ul de intrare. Dac data ateptat este un char, intrarea se ntrerupe dup primul caracter. Dac este vorba de un int sau double, intrarea se ntrerupe la primul caracter care nu se potrivete ca tip de dat, cum ar fi un spaiu. Exemplu int i, j, k; char ch; float x; Instruciunea Data Coninutul variabilei dup intrare cin >> i; 32 i = 32 cin >> i >> ch >> x; 25 A 16.9 i = 25 ch = A x = 16.9 cin >> i >> j >> x; 12 8 i = 12 j = 8 Programul ateapt al treilea numr cin >> i >> x; 46 32.4 15 i = 46 x = 32.4 15 este pstrat pentru o intrare ulterioar

Caracterul newline
Fiecare linie are un caracter invizibil care marcheaz sfritul su caracterul newline. Pentru a determina urmtoarea valoare de intrare, operatorul >> trece peste caracterul newline, n cazul n care acesta exist. Atunci cnd utilizm tastatura, caracterul newline este introdus prin apsarea lui Return sau Enter. Programul poate genera un newline folosind manipulatorul endl ntr-o instruciune de ieire. n C++ putem s ne referim la caracterul newline folosind simbolurile \n. Dei \n const din dou caractere, el se refer la unul singur caracterul newline. Aa cum putem pstra litera A n variabila ch de tip char prin instruciunea char ch = A; tot aa putem pstra caracterul newline ntr-o variabil: 2

Programarea calculatoarelor i limbaje de programare I

ch = \n; Exemplu Cnd avem o secven de citiri, putem introduce valorile n mai multe feluri: cin >> i; 25 A 16.9\n 25\n 25A16.9\n cin >> ch; A\n Citirea se oprete cnd cin >> x; 16.9\n tipul de dat nu mai corespunde Dup citire, variabilele vor avea urmtoarele valori: i = 25 ch = A x = 16.9

Citirea datelor de tip caracter folosind instruciunea get


Am vzut c operatorul >> ignor orice spaiu aprut n stream-ul de intrare. S presupunem c ch1 i ch2 sunt variabile de tip char i c programul execut instruciunea cin >> ch1 >> ch2; Dac stream-ul de intrare este R 1 Atunci operatorul de extracie va stoca R n ch1, ignor spaiul i apoi pstreaz 1 n ch2. Ce se ntmpl, ns, dac am fi dorit, de fapt, s introducem trei caractere: R, spaiu i 1? Cu operatorul de extracie acest lucru nu este posibil. Vom folosi funcia get care ncarc urmtorul caracter fr a ignora spaiile. Acest apel de funcie arat astfel: cin.get(ch); Specificm numele istream-ului, adic cin, apoi punem semnul . (punct) urmat de numele funciei i lista ei de parametri. Apelul funciei get folosete sintaxa apelului funciilor void i nu a celor care ntorc o valoare. Acest apel de funcie este, deci, o instruciune de sine stttoare. Parametrul funciei get trebuie s fie o variabil. Acesta este un exemplu prin care se apeleaz o funcie din clasa istream funcia get pentru un obiect al acestei clase obiectul cin. Putem folosi urmtoarele trei apeluri ale lui get: cin.get(ch1); cin.get(ch2); cin.get(ch3); sau cin >> ch1; cin.get(ch2); cin >> ch3; Dac stream-ul de intrare este tot R 1 atunci variabilele ch1, ch2 i ch3 vor stoca ch1 = R; ch2 = ; ch3 = 1; Exemplu

Programarea calculatoarelor i limbaje de programare I

cin >> ch1; cin >> ch2; cin >> ch3;

A B\n CD\n

ch1 = A; ch2 = B; ch3 = C; ch1 = A; ch2 = ; ch3 = B; ch1 = A; ch2 = B; ch3 = \n;

cin.get(ch1); A B\n cin.get(ch2); CD\n cin.get(ch3); cin >> ch1; A B\n cin >> ch2; CD\n cin.get(ch3);

Ignorarea caracterelor folosind funcia ignore


Funcia ignore este asociat cu tipul de dat istream, fiind o funcie definit n aceast clasa istream. Este folosit pentru a sri peste caractere din stream-ul de intrare. Este o funcie cu doi parametri, iar un exemplu de apel este urmtorul: cin.ignore(200, \n); Primul parametru este o expresie int, iar al doilea una char. Acest apel al funciei spune calculatorului s ignore urmtoarele 200 de caractere de intrare sau s sar pn ntlnete caracterul newline, n funcie de care dintre ele apare prima. Exemplu cin >> i >> j; 957 34 1235\n i = 957; cin.ignore(100, \n); 128 96\n j = 34; cin >> k; k = 128; cin >> ch; cin.ignore(100, B); cin >> i; cin.ignore(2, \n); cin >> ch; A 22 B 16 C 19\n ch = A; i = 16;

ABCDEF\n

ch = C;

Intrri i ieiri interactive


Un program interactiv este unul prin care utilizatorul comunic direct cu calculatorul. Multe dintre programele scrise de noi vor fi interactive, dnd i o anumit etichet codului. Atunci cnd dorim s cerem utilizatorului s introduc o dat n program, este util s i afim nainte un mesaj prin care s i explicm ce trebuie s introduc. De asemenea, programul ar trebui s tipreasc toate datele introduse pentru ca utilizatorul s se poat verifica. Aceasta se numete tiprire n ecou. Programul de mai jos arat cum poate fi scris un cod interactiv. Exemplu #include <iostream> #include <iomanip> using namespace std; int main() { int codNumeric;

Programarea calculatoarelor i limbaje de programare I

int cantitate; double pretUnitar; double pretTotal; cout << "Introduceti comandat:" << endl; cin >> codNumeric; codul numeric al produsului

cout << "Introduceti cantitatea:" << endl; cin >> cantitate; cout << "Introduceti produs:" << endl; cin >> pretUnitar; pretul unitar pentru acest

pretTotal = cantitate * pretUnitar; cout.setf(ios::fixed, ios::floatfield); cout << << << pretUnitar << cout << "Produsul " << codNumeric ", cantitatea " << cantitate ", pretul unitar " << setprecision(2) " lei " << endl; "Total: " << pretTotal << endl;

<<

return 0; } n timpul rulrii acestui program se va tipri cte un text care va arta utilizatorului care este urmtoarea valoare ateptat. Exemplu Introduceti codul numeric al produsului comandat 4671 Introduceti cantitatea: 10 Introduceti pretul unitar pentru acest produs: 272.55 Produsul 4671, cantitatea 10, pretul unitar 272.55 lei Total: 2725.50 Volumul informaiei afiate depinde de cel care va folosi programul. Dac el este destinat unor persoane nefamiliarizate cu calculatorul, mesajele vor fi mai detaliate. Dac programul este folosit frecvent de aceeai persoan, putem da mesaje mai scurte sau se pot introduce mai multe valori pe aceeai linie.

Intrri i ieiri neinteractive


Dei tindem s dm exemple de programe interactive, multe dintre programele folosite n viaa real sunt neinteractive. Acestea sunt programe care prelucreaz cantiti mari de date, greu de introdus interactiv fr erori. Pentru acest tip de programe, datele se pstreaz n fiiere de date pregtite anterior. Aceasta permite verificare i corectarea datelor nainte de rularea programului.

Programarea calculatoarelor i limbaje de programare I

4.2

Intrri i ieiri din fiiere

Fiierul este o zon pe un suport de stocare, de exemplu hard disc, desemnat printr-un nume, care pstreaz o colecie de date, de exemplu codul programului scris cu un editor. Un program poate citi datele dintr-un fiier n aceeai manier n care le citete de la tastatur. Se poate scrie n fiier la fel cum se scrie pe ecran. Atunci cnd programul ajunge s lucreze cu cantiti mari de date, este de preferat s folosim fiierele. Acestea pot fi scrise cu un editor de texte, corectate i salvate pe disc. Totodat, nu suntem obligai s introducem toate datele dintr-o singur dat.

Modul de utilizare a fiierelor


Pentru a folosi un fiier n operaiile I/O trebuie s parcurgem patru pai. 1. Cerem preprocesorului s includ fiierul header fstream; 2. Folosim instruciuni de declarare pentru a declara stream-urile; 3. Pregtim fiierele pentru citire i scriere prin instruciunea open; 4. Specificm numele stream-ului n fiecare instruciune de citire sau de scriere. Includerea fiierului header fstream Vom modifica programul care msoar consumul unui autoturism la 100 km pentru ca s citeasc datele dintr-un fiier. Exemplu #include <fstream> using namespace std; int main() { float float float float float float float

cant1; cant2; cant3; cant4; indicatiePlecare; indicatieSosire; litriPerKm;

ifstream inConsum; ofstream outConsum; inConsum.open("incons.dat"); outConsum.open("outcons.dat"); inConsum >> cant1 >> cant2 >> cant3 >> cant4 >> indicatiePlecare >> indicatieSosire; litriPerKm = (cant1 + cant2 + cant3 + cant4)*100.0/ (indicatieSosire - indicatiePlecare); outConsum << "Consumul este " << litriPerKm << " litri per km." << endl;

Programarea calculatoarelor i limbaje de programare I

return 0; } Mai nti folosim directiva de preprocesare #include <fstream> Prin acest header se definesc dou noi tipuri de date, ifstream i ofstream. Cele dou tipuri de dat reprezint, primul, un stream de caractere provenind de la un fiier, iar al doilea un stream de caractere care conduce ctre un fiier. Toate operaiile valabile pentru un istream: >>, get sau ignore sunt valabile i pentru tipul ifstream. Operaiile folosite pentru un ostream: <<, endl, setw, setprecision se pot folosi i pentru un ofstream. Declararea stream-urilor pentru fiiere Obiectele de tip stream se declar la fel ca orice variabil Exemplu int unInt; float unFloat; ifstream unFisier; ofstream altFisier; Obiectele cin i cout nu trebuie declarate n fiecare program pentru c ele sunt declarate n fiierul iostream, citirile de la tastatur i scrierile pe ecran fiind operaii frecvente. Spre deosebire de ele, stream-urile pentru lucrul cu fiiere trebuie declarate n program pentru c fiecare aplicaie folosete propriile fiiere de date. Pentru programul nostru declarm dou stream-uri: ifstream inConsum; ofstream outConsum; De notat c ifstream se utilizeaz doar pentru fiiere de intrare, iar ofstream doar pentru fiiere de ieire. Prin intermediul unui obiect ifstream se pot face doar citiri, iar prin intermediul unui obiect ofstream se pot face doar scrieri. Deschiderea fiierelor Trebuie s pregtim acum fiierele pentru citire sau scriere, deci le deschidem. Ne propunem s citim din stream-ul tip fiier inConsum i s scriem n streamul outConsum. Deschidem fiierele folosind urmtoarele instruciuni: inConsum.open("incons.dat"); outConsum.open("outcons.dat"); Funcia open are un singur argument cuprins ntre ghilimele. Prima instruciune este un apel al funciei open asociate cu tipul de dat ifstream, iar a doua apeleaz funcia open asociat cu ofstream. Funcia open asociaz variabila stream din program cu un fiier fizic pe disc. Prima instruciune realizeaz o conexiune ntre obiectul inConsum i fiierul incons.dat. A doua instruciune leag obiectul outConsum de fiierul outcons.dat. inConsum este conectat cu incons.dat aa cum cin este legat de tastatur. Mai departe, aciunea depinde de tipul de stream. Pentru un fiier de intrare, funcia open poziioneaz markerul de citire pe primul element din fiier. Pentru un fiier de ieire, funcia verific dac acesta exist. Dac exist, terge vechiul coninut al su. Dac nu exist, l creeaz. Apoi markerul de scriere este aezat pe prima poziie.

Programarea calculatoarelor i limbaje de programare I

Folosim noiunile de marker de citire sau de scriere pentru a reprezenta locul din care se va citi dintr-un stream de intrare, respectiv se va scrie ntr-un stream de ieire. Exemplu inConsum outConsum 23.2 _ 17.4 19.8 16.7 22451 23544 Deschiderea fiierelor trebuie realizat naintea oricrei utilizri a lor deoarece funcia open le pregtete pentru citire sau scriere. Specificarea stream-urilor n instruciuni I/O Pentru citirea i scrierea din fiier nu va trebui dect s nlocuim obiectele cin i cout cu obiectele de tip stream de fiier declarate mai devreme. Exemplu inConsum >> cant1 >> cant2 >> cant3 >> cant4 >> indicatiePlecare >> indicatieSosire; outConsum << "Consumul este " << litriPerKm << " litri per km." << endl; Cel mai interesant este c C++ folosete o sintax uniform pentru operaiile I/O, indiferent dac este vorba despre fiiere sau dispozitive I/O.

4.3

Erori de citire

La citirea datelor de la tastatur sau dintr-un fiier pot aprea erori. S presupunem c programul ne cere s introducem un numr ntreg, iar noi introducem caractere. Operaia de intrare eueaz datorit datelor de intrare invalide. n terminologia C++ stream-ul cin intr ntr-o stare de eroare - fail state. Dac un stream intr ntr-o astfel de stare, orice alt operaie ulterioar asupra sa este anulat. Din pcate, calculatorul nu oprete programul i nu d niciun mesaj de eroare n astfel de situaii. De cele mai multe ori erorile de intrare apar din cauza nepotrivirii tipurilor de dat. Exemplu int i = 10; int j = 20; int k = 30; cin >> i >> j >> k; cout << i: << i << j: << j << k: << k; Dac tastm 1234.56 7 89 programul afieaz i: 1234 j: 20 k: 30 Un alt motiv pentru care un stream intr n fail state este incercarea de deschidere a unui fiier de intrare care nu exist. S presupunem c avem pe disc fiierul myfile.dat i scriem urmtoarele instruciuni care i propun s lucreze cu acest fiier: ifstream inFisier; inFisier.open(myfil.dat); 8

Programarea calculatoarelor i limbaje de programare I

inFisier >> i >> j >> k; Datorit scrierii incorecte a numelui de fiier, inFisier va intra n fail state. Ca urmare, variabilele i, j i k vor avea nite valori nedeteminate. Un stream de citire dintr-un fiier intr n fail state atunci cnd se citete din fiier dincolo de caracterul EOF, cel care marcheaz finalul fiierului.

4.4

Scrierea aplicaiilor

Problemele pe care le-am prezentat pn acum au fost simple i uor de programat. n acest moment putem scrie i aplicaii mai complexe i de aceea trebuie s vedem cum putem concepe corect o aplicaie. Vom vorbi despre descompunerea funcional i despre proiectarea orientat pe obiecte.

Descompunerea funcional
Aceast este o tehnic de dezvoltare a unei pri a unui program sau chiar a unui program de dimensiuni reduse prin care problema este mprit n subprobleme mai uor de rezolvat, soluii care creeaz o soluie global a ntregii probleme. Printr-o astfel de descompunere crem o structur ierarhic numit structur arborescent. Rezolvarea problemei Pas I Pas II Pas III abstract Nivelul 0

pas abstract Subproblema I Pas A Pas B Subproblema II Pas C Pas D Subproblema III Pas E Pas F Nivelul 1

Subproblema A Pas 1

Subproblema B Subproblema C Pas 2 Pas 3 Pas 4 Pas 5 Pas 6 Subproblema 2 Pas a Pas b Pas c 9

Subproblema F Pas 7 Pas 8 Nivelul 2

pas concret

Nivelul 3 concret

Programarea calculatoarelor i limbaje de programare I

Paii haurai conin suficiente detalii pentru a putea fi implementai n C++. Cei nehaurai trebuie descompui n continuare. Fiecare celul este un modul. Modulele sunt elemente de baz ntr-o descompunere funcional. Pentru conceperea unui modul trebuie s parcurgem urmtorii pai: 1. S schim o soluie a problemei 2. S descriem paii majori 3. Dac un pas este suficient de simplu pentru a putea fi implementat, nu mai necesit descompuneri ulterioare 4. Dac pasul poate fi gndit ca o serie de pai mai mici, este nc un pas abstract

Proiectarea orientat pe obiecte


Descompunerea funcional poate fi privit ca o metod de gsire a soluiei unei probleme cu accent pe algoritmi i aciunile care trebuie realizate. Datele, n acest caz, joac un rol secundar. Proiectarea orientat pe obiecte se focalizeaz pe entiti (obiecte) i operaiile posibile asupra acestor entiti. Exemplu O problem bancar poate avea nevoie de un obiect contBancar cu operaiile asociate DeschideCont, ScrieCec i CreeazaDepozit. Obiectul contBancar const din date numarCont i balantaCurenta. Primul pas n proiectarea orientat pe obiecte este identificarea obiectelor din problem i a operaiilor asociate. Soluia final va fi exprimat n termeni de obiecte i operaii. Datele joac aici un rol determinant. n C++ operaiile asociate cu o clas sunt scrise ca funcii i se numesc funcii membre. O funcie membr este apelat prin numele unui obiect al clasei urmat de un punct i de numele funciei cu lista de parametri. Exemplu contBancar.DeschideCont(1000, tip1); Datele care compun obiectul se numesc date membre. Instanele unei clase se numesc obiecte, n timp ce instanele tipurilor de date predefinite cum ar fi int se numesc variabile. Proiectarea orientat pe obiecte conduce la un program care folosete o colecie de obiecte. Fiecare obiect rspunde de o parte din soluie, iar obiectele comunic ntre ele prin apelarea funciilor membre. Proiectarea orientat pe obiecte se preteaz la scrierea proiectelor mari din urmtoarele trei motive: 1. Obiectele dintr-un program modeleaz obiecte din problema de rezolvat; 2. Este posibil furnizarea i utilizarea de biblioteci de clase scrise de diverse firme sau persoane independente; 3. Se folosete un concept fundamental numit motenire care permite adaptarea unei clase la particularitile problemei fr a modifica codul scris anterior. Pentru crearea unei soluii software optime se urmeaz un proces detaliat pentru obinerea unei analize a cerinelor sistemului (requirments) i proiectarea acestuia (design) astfel nct s satisfac cerinele. Programatorii experimentai cunosc faptul c orict de simpl ar fi problema pe care o au de rezolvat, timpul

10

Programarea calculatoarelor i limbaje de programare I

petrecut cu analiza i proiectarea poate salva foarte mult timp care se poate pierde cu dezvoltarea unui sistem greit conceput. Unified Modeling Language (UML) Exist multe procedee pentru analiza i proiectarea orientat pe obiecte. Pentru totate acestea se folosete un limbaj grafic de comunicare a rezultatelor numit Unified Modeling Language (UML). Prima versiune a acestui limbaj a fost lansat n anul 1996 de ctre James Rumbaugh, Grady Booch i Ivar Jacobson de la Rational Software Corporation. n acelai timp, organizaia non-profit Object Management Group (OMG) a lansat, la iniiativa companiilor HP, IBM, Microsoft, Oracle i Rational Software, o propunere de creare a unui limbaj unic de modelare. UML a fost limbajul adoptat de OMG care, ncepnd cu anul 1997 asigur revizuirea permanent a sa. UML este o schem de reprezentare grafic pentru modelarea sistemelor orientate pe obiecte. Una dintre cele mai atractive caracteristici ale sale este flexibilitatea. UML este extensibil i independent de multele procese de analiz i proiectare orientate pe obiecte. Tehnologia obiectelor a devenit indispensabil n industria software, iar UML este din ce n ce mail folosit. Specificaiile complete ale UML sunt disponibile la http://www.uml.org.

11

S-ar putea să vă placă și