Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Sistemul de intrare/iesire din C++
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 

Pe langa faptul ca poate fi folosit sistemul de intrare/iesire (I/O) din C, in C++ mai este definit inca un sistem complet integrat, care permite operarea cu obiecte de tipuri definite de utilizatori. Ca si sistemul I/O din C, cel din C++ opereaza prin streamuri (fluxuri). Un stream este o entitate logica in care se intoduc (se insereaza) sau se extrag informatii. Toate streamurile se comporta in mod asemanator, chiar daca echipamentele fizice la care sunt conectate pot sa difere substantial. u3p13pm
Functiile bibliotecii de streamuri sunt numeroase, dar in continuare vor fi descrise numai cele fundamentale, iar pentru alte detalii se poate consulta biblioteca I/O a compilatorului C++. Fisierul antet iostream.h defineste interfata cu biblioteca de streamuri prin mai multe clase si functii. Clasa de nivel cel mai mic este clasa streambuf, care defineste operatiile de baza de I/O. Cu exceptia situatiilor in care se doresc propriile clase de I/O, nu se deriveaza direct din clasa streambuf, ci din clasa din al doilea nivel de ierarhie, numita clasa ios. Clasa ios accepta I/O formatate si din ea sunt derivate clasele istream, ostream, iostream, pentru streamuri de intrare, iesire, respectiv intrare/iesire, precum si alte clase pentru utilizarea fisierelor pe disc si formatarea in memorie.
La inceperea executiei unui program C++, in mod automat se deschid patru streamuri standard incorporate. Aceste streamuri sunt:

cin Intrare standard Tastatura cout Iesire standard Ecran cerr Iesire standard pentru eroare Ecran clog Versiune cu buffer de memorie pentru cerr Ecran

Streamurile cin, cout si cerr corespund streamurilor stdin, stdout si stderr din C.

6.1 Functii de I/O pentru tipurile predefinite

Operatiile de I/O din C++ se efectueaza folosind functiile operator de insertie << si operator de extragere >>. Streamurile pot fi considerate ca recipienti de caractere aranjate intr-o anumita ordine in care se introduc si din carte se extrag date. Functiile de operare asupra streamurilor specifica modul in care se executa conversia intre un sir de caractere din stream si o variabila de un anumit tip. Aceste functii operator sunt definite in clasa ostream, respectiv istream, pentru toate tipurile predefinite ale limbajului, iar pentru tipurile definite de utilizator ele pot fi supraincarcate.
De exemplu, in clasa ostream sunt definite functii operator de insertie << astfel:




class ostream : public virtual ios A
// ………... public: ostream& operator << (const char*); // siruri ostream& operator << (char); ostream& operator << (short); ostream& operator << (int); ostream& operator << (long); ostream& operator << (double); ostream& operator << (const void*); // pointeri
……………
S;

In clasa istream sunt definite functii operator de extractie >> astfel:

class istream : public virtual ios A
// ………... public: istream& operator >> (char*); // siruri istream& operator >> (char&); istream& operator >> (short&); istream& operator >> (int&); istream& operator >> (long&); istream& operator >> (double&);
……………
S;

? Exemplul 6.1

Functia de citire de la consola a unei secvente de numere intregi separate prin spatii albe (whitespace adica unul din caracterele blanc, tab, newline, carriage return, formfeed) poate arata asfel:

void fint()A int size = 10; int arraya10i; for(int i=0;i<size;i++)A if (cin >> arrayaii) cout << arrayaii << " "; else A cout << "eroare non-int"; break;
S
S
S

O intrare diferita de intreg va cauza eroare in operatia de citire si deci oprirea buclei for. De exemplu, din intrarea:
1 2 3 4.7 5 6 7 8 9 0 11 functia fint() va citi primele patru numere, dupa care apare eroare in operatia de intrare, citirea numerelor intregi se intrerupe si pe ecran apare mesajul:
1 2 3 4 eroare non-int
Caracterul punct este lasat in streamul de intrare, ca urmator caracter de citit.
?

O alta solutie pentru citirea unei secvente de intrare este prin folosirea uneia din functiile get() definite in clasa iostream astfel:

class iostream : public virtual ios A
// …… istream& get(char& c); istream& get(char* p, int n, char ch=’\n’);
S;

Aceste functii treateaza spatiile albe la fel ca pe toate celelalte caractere. Functia get(char& c) citeste un singur caracter in argumentul c. De exemplu, o functie fg() de copiere caracter cu caracter de la intrare (streamul cin) la iesire (streamul cout) poate arata astfel:

void fg()A char c;
while(cin.get(c)) cout << c;
S

Si functia operator >> () are un echivalent ca functie de scriere la consola fara supraincarcarea operatorului >>, numita functia put(), astfel incat functia fg() se poate rescrie astfel:

void fg()A char c;
while(cin.get(c)) cout.put(c);
S

Functia cu trei argumente istream::get() citeste cel mult n-;1 caractere intr-un tablou de caractere care incepe la adresa p si introduce, ca ultim caracter in tablou, caracterul 0. Cel de-al treilea argument specifica caracterul terminator al citirii, implicit caracterul newline (‘\n’), care este lasat ca primul caracter necitit in stream. O utilizare tipica a functiei get() cu trei argumente este citirea unei linii de intrare intr-un buffer de dimensiune fixa, pentru o analiza ulterioara. De exemplu: void fbuf()A char bufa100i; cin >> buf; // operatie suspecta, pot apare erori

cin.get(buf,100,'\n'); // citire sigura
S

Instructiunea cin >> buf este suspecta deoarece un sir de intrare cu mai mult de 99 caractere va produce depasire la scrierea in buffer si deci erori de executie. Citirea folosind functia get() introduce maximum n-1 caractere in buffer, urmate de caracterul 0. Daca in sirul de intrare este gasit caraterul terminator '\n',inainte de terminarea unei secvente de n-1 caractere, acesta este lasat in streamul de intrare, iar in buffer se introduce, de asemenea, caracterul 0.

6.2 Functii de I/O pentru tipuri definite de utilizator

Functiile de I/O pentru tipuri definite de utilizator se obtin prin supraincarcarea operatorilor de insertie si de extragere, care au urmatoarea forma generala:

ostream& operator<<(ostream& os,tip_clasa nume)A
// corpul functiei return os;
S istream& operator<<(istream& is,tip_clasa& nume)A
// corpul functiei return is;
S

Primul argument al functiei este o referinta la streamul de iesire, respectiv de intrare. Pentru functia operator de extragere << al doilea argument este dat printr-o referinta la obiectul care trebuie sa fie extras din stream; in aceasta referinta sunt inscrise datele extrase din streamul de intrare. Pentru functia operator de insertie >> al doilea argument este dat prin tipul si numele obiectului care trebuie sa fie inserat, sau printr-o referinta la acesta. Functiile operator de insertie si extractie returneaza o referinta la streamul pentru care au fost apelate, astfel incat o alta operatie de I/O poate fi adaugata acestuia.
Functiile operator << sau >> nu sunt membre ale clasei pentru care au fost definite, dar pot (si este recomandabil) sa fie declarate functii friend in clasa respectiva. Motivul pentru care o functie operator << sau >> nu poate fi membru al unei clase este simplu de observat: atunci cand o functie operator de orice fel este membru al unei clase, operandul din stanga, care este un obiect din clasa respectiva, este cel care genereaza apelul si transmite implicit functiei pointerul this. Ori, in cazul functiilor operator << sau >> operandul din stanga trebuie sa fie un stream, nu un obict din clasa respectiva, deci aceste functii nu pot fi functii membre ale claselor.
Ca exemple de supraincarcare a functiilor operator << si >>, se reiau clasele definite in lucrarile precedente, Complex si String, si li se adauga aceste functii. class Complex A double x, y; public:
Complex()Ax = 0; y = 0S
Complex(double r, double i)A x = r; y = i;
S
………….. friend ostrem& operator << (ostrem& os,
Complex z); friend istream& operator >>(istream& is,
Complex& z);
S; ostream& operator<<(ostream& os, Complex& z)A os << ‘(‘ << z.x << ’,’<< z.y << ‘)’; return os;
S istream& operator>>(istream& is, Complex z)A is >> z.x >> z.y; return is;
S

class StringA char *str; int size; public:
String()Astr = 0; size = 0;S
String(const char *p);
String(const String& r);
IString();
String operator=(String op2); friend ostream& operator <<(ostream& stream, const String &r); friend istream& operator >>(istream& stream,
String &r);
S; ostream& operator <<(ostream &stream, const String &r)A for (int i=0;i<r.size;i++) stream << r.straii; return stream;
S istream& operator >>(istream &stream, String &r)A char bufa256i; cin.get(buf,256); r = buf; return stream;
S

? Exemplul 6.2

Fie functia fc() in care se citesc de la consola un numar complex (de tip Complex) si un sir (de tip String) care apoi sunt afisate pe ecran.

void fc()A
Complex z; cout << "Introduceti x, y :"; cin >> z; cout << "z = " << z << '\n'; cin.get(); int size = 10; char bufai = "9999999999"; cout << "Introduceti un sir:"; cin.get(buf,size,'\n');

for (int i=0;i<size;i++) cout << bufaii; cout << endl;
S

Executia acestei functii produce urmatoarele mesaje la consola:

Introduceti x, y: 1.3 4.5 z = (1.3,4.5)
Introduceti un sir:123456
123456

?

Functia operator de extragere a clasei String permite citirea sigura a unor siruri de caractere de o dimensiune maxima impusa (255 de caractere in exemplul dat). Extragerea unor siruri de o dimensiune oarecare este lasata ca un exercitiu simplu pentru cititor.

6.3 Starea streamurilor

Fiecare stream (istream sau ostream) are asociata o stare, memorata intr-un intreg in clasa ios, iar conditiile nestandard sau erorile aparute in operatiile cu acesta pot fi setate sau testate folosind operatii publice ale clasei de baza ios. Valorile folosite pentru descrierea starii unui stream si functiile de testare a starii definite in clasa de baza ios sunt urmatoarele:

class ios A

// ……. public: enum io_state A goodbit=0, eofbit=1, failbit=2, badbit=4
S; int rdstate() const; int good() const; int eof() const; int fail() const; int bad() const;
// ……..
S;

Functia rdstate() returneaza 0 daca nu a aparut nici o eroare si nici nu a a fost intalnit indicatorul de sfarsit al streamului (end of file, eof). Fiecare stare in parte poate fi obtinuta si prin apelul uneia din functiile good(), eof(), fail() sau bad().
Daca starea este good() sau eof(), operatia precedenta s-a desfasurat cu succes. Aplicarea unei operatii de insertie intr-un stream care nu se afla in starea good()este o operatie nula si nu modifica streamul. O operatie de extragere a unor date dintr-un stream care cauzeaza starea fail() lasa, in general, nemodificata variabila in care urma sa aiba loc inscrierea.
Atunci cand un stream este utilizat intr-o operatie de testare (ca de exemplu, in expresiile deja utilizate mai sus: while(cin.get(c))) este testata starea streamului si testul returneaza valoare 0 daca este setat unul din bitii failbit sau badbit. Aceasta operatie de testare este posibila prin conversia unui stream intr-un pointer, executa de functia supraincarcata operator de conversie a clasei ios: operator void*() const;

6.4 Formatarea I/O

In exemplele prezentate pana acum au fost folosite operatii de I/O neformatate, in care transformarea unui obiect intr-o secventa de caractere a fost executata conform unor reguli implicite. In C++ se pot specifica formate diferite de cele implicite pentru operatiile de intrare si de iesire, in mod asemanator cu formatele introduse prin functiile printf() si scanf() din C.
Exista doua posibilitati de formatare a datelor in C++. Prima posibiltate este cea oferita de accesul la variabilele si functiile membre ale clasei de baza ios care se refera la formatarea datelor. Cea de-a doua posibilitate o reprezinta utilizarea unor functii speciale, numite manipulatori, care pot fi incluse in operatii (expresii) de I/O.

6.5.1 Formatarea I/O folosind membrii clasei ios

Clasa ios controleaza conexiunea dintre un stream si bufferul utilizat pentru operatiile de intrare si de iesire, avand astfel posibiltatea de specifica modul in care sunt introduse sau extrase caracterele. Clasa ios contine date membre care memoreaza informatii despre baza de numeratie folosita (zecimal, octal, hexazecimal), depre precizia cu care se scriu sau se citesc numerele in virgula mobila, etc, precum si functii care permit setarea sau examinarea acestora pentru fiecare stream. Flagurile (indicatorii) de formatare din clasa ios si functiile de acces la acestia sunt:

class ios A public:
// flaguri (indicatori) de formatare enum A skips=0x00001, // ignor spatii la intrare left=0x00002, // completare dupa valoare right=0x00004, // compl. inainte de val. internal=0x0008, // compl.format intern dec=0x0010, // zecimal oct=0x0020, // octal hex=0x0040, // hexazecimal showbase=0x080, // afiseaza baza showpoint=0x0100, // af. zerouri din fata nr. uppercase=0x0200, // caractere uppercase showpos=0x0400, // explicit + scientific=0x0800, // .dddddd Edd fixed=0x1000, // dddd.dd unitbuf=0x2000, // dupa fiec. op. iesire
S;
// functii de formatare int width(int w); // largime camp int width() const;

char fill(char); // caracter de umplere char fill() const;

long flags(long f); long flags() const;

long setf(long); // setare indicatori long setf(long setbits, long field); long unsetf(long);

int precision(int); // prec. nr. v. mobila int precision() const;
S;

Functia setf() cu un singur argument este utilizata pentru activarea unuia sau mai multor indicatori de formatare. Fiind o functie membra a clasei ios, ea trebuie sa fie apelata pentru un anumit obiect (stream), ceea ce inseamna ca nu exista o stare globala de formatare, ci fiecare stream are propria lui stare. Indicatorii de formatare pot fi modificati individual, prin apeluri separate ale functiei setf() sau grupati intr-o expresie logica OR (SAU). De exemplu, instructiunile: cout.setf(ios::hex); cout.setf(ios::showbase); sunt echivalente cu instructiunea: cout.setf(ios::hex | ios::showbase); si au ca efect afisarea unui numar in format hexazecimal, cu reprezentarea explicita a bazei folosite. Dupa o astfel de formatare, instructiunea: cout << 100; va afisa la consola: 0x64.
Dat fiind ca indicatorii de formatare sunt definiti in interiorul clasei ios, pentru a avea acces la valorile lor, acestia trebuie sa fie insotiti de specificarea domeniului clasei ios (de exemplu, ios::hex).
Functia setf() cu doua argumente este o forma supraincarcata care permite modificarea acelor stari care sunt reprezentate prin campuri compuse din mai multi biti. De exemplu, baza numerica de afisare implica un camp format din trei biti (dec, oct si hex) din care numai unul poate fi setat la un moment dat. Pentru o astfel de setare se apeleaza functia setf() avand ca prim argument (setbits) indicatorul care trebuie sa fie setat, al doilea fiind un pseudoargument (field), care defineste campul celui dintai.
Pseudoargumentele definite in clasa ios sunt: ios::basefield (pentru baza de numeratie, format din bitii dec, oct, hex), ios::adjustfield (pentru campul de aliniere format din bitii left si right) si ios::floatfield (pentru campul de afisare a numerelor cu virgula mobila, format din bitii scientific si fixed).
De exemplu, fiecare din instructiunile:

cout.setf(ios::oct, ios::basefield); // octal cout.setf(ios::dec, ios::basefield); // zecimal cout.setf(ios::hex, ios::basefield); // hexazecimal

seteaza baza de numeratie fara efecte asupra altor parti ale starii streamului.

Functia unsetf() este complementara functiei setf() si are ca efect stergerea unuia sau mai multor indicatori de format. Functia unset() opereaza intr-un mod asemanator cu functia setf().

? Exemplul 6.3

Fie urmatoarea functie care formateaza streamuri folosind functiile membre ale clasei ios.

void ff()A cout.setf(ios::uppercase | ios::scientific); cout <<100.12 <<’\n’; cout.unsetf(ios::uppercase); cout <<100.12 <<’\n’;
S

La executia acestei functii se afiseaza la consola numarul 100.12 in urmatoarele formate, stabilite folosind functiile setf() si unsetf():

1.0012E+002
1.0012e+002
?

Functia flags() permite examinarea starii indicatorilor de format, fara ca acestia sa fie modificati. Functia flags() returneaza o data de tipul long, care contine valoarea fiecarui indicator de format intr-un bit aflat pe pozitia corespunzatoare definirii din clasa ios.

Functia width() specifica o marime de camp minim pentru reprezentarea unui numar. Dupa apelul functiei width(w), daca valoarea inserata in stream foloseste mai putin de w caractere, atunci se completeaza campul pana la aceasta lungime cu caracterul de completare curent (implicit spatiu). Daca pentru reprezentarea valorii inserate in stream sunt necesare mai mult de w caractere, nu se trunchiaza numarul, ci se intoduc toate caracterele acestuia, chiar daca se depaseste valoarea w.

Functia fill() specifica caracterul de completare a campurilor, folosit atunci cand numarul de caractere necesare pentru reprezentarea unui numar este mai mic decat marimea minima setata.

Functia precision() este utilizata pentru a determina numarul de cifre care sa fie afisate dupa punctul zecimal.

? Exemplul 6.4

Se considera urmatorul program care permite afisarea starii indicatorilor de formatare ai unui stream:

void showflags()A long f, i, j; char indica15ia12i = A
"skipws",
"left",
"right",
"internal",
"dec",
"oct",
"hex",
"showbase",
"showpoint",
"uppercase",
"showpos",
"scientific",
"fixed",

"unitbuf",
S;
// se citeste starea indicatorilor f = cout.flags(); if (f) for (i=1,j=0; i<=0x2000; i = i<<1,j++)A if(i & f) cout << "Este activat "
<< indicaji << "\n";
S else cout<< "Nu este activat nici un indicator \n";
S void main()A cout << 1234.56 <<endl; showflags(); cout.setf(ios::right| ios::showpoint | ios::fixed); cout.fill('*'); cout.width(20); cout << 1234.56 << "\n"; showflags(); cout.unsetf(ios::right|ios::showpoint|ios::fixed); cout << 1234.56 <<endl; showflags();
S

La executia acestui program se obtin urmatoarele mesaje la consola:

1234.56
Nu este activat nici un indicator
*********1234.560000
Este activat right
Este activat showpoint
Este activat fixed
1234.56
Nu este activat nici un indicator

Aceste mesaje evidentiaza corespondenta dintre comanda de formatare apelata, numele indicatorilor de formatare modificati si efectul acestora asupra modului de afisare a unor date. De asemenea, folosind aceasta functie se pot experimenta si alte comenzi de formatare a streamurilor. ?
6.5.2 Formatarea I/O folosind manipulatori

A doua posibilitate de a modifica modul de formatare ai unui stream este aceea de a folosi functiile speciale numite manipulatori. O parte din manipulatorii care se pot folosi pentru formatarea streamurilor sunt prezentati in tabelul de mai jos:

Manipulator Scop Intrare/Iesire dec Intrare/iesire de date in zecimal Intrare si iesire endl Insereaza un caracter newline Iesire ends Insereaza un null Iesire flush Goleste un stream Iesire hex Intrare/iesire in hexazecimal Intrare si iesire oct Intrare/iesire in octal Intrare si iesire resetiosflags(long f) Dezactiveaza indicatorii f Intrare si iesire setbase(int base) Seteaza baza numerica Iesire setfill(int ch) Seteaza caracterul de completare Iesire setiosflags(long f) Activeaza indicatorii f Intrare si iesire setprecision(int p) Stabileste nr. de cifre pt. precizie Iesire setw(int w) Stabileste dim. min. a campului Iesire
ws Omite spatii libere de la inceput Intrare

Din acest tabel se poate observa ca cei mai multi manipulatori dubleaza functiile de formatare din clasa ios.

? Exemplul 6.5

Folosind aceeasi functie showflags() din exemplul precedent, se poate observa modul de formatare a streamurilor folosind manipulatori si corespondenta dintre acestia si functiile de formatare membre ale clasei ios. Executia functiei:

void fm()A cout<<1234.56<<endl; showflags(); long flags=ios::right| ios::showpoint | ios::fixed; cout <<setw(20)<<setfill('*') <<setiosflags(flags); cout << 1234.56<<endl; showflags(); cout << resetiosflags(flags); cout << 1234.56; showflags();
S

La executia acestei functii se afoseaza aceleasi mesaje la consola ca si la executia programului precedent, deci se obtin aceleasi formate ale streamurilor ca si prin executia functiilor membre ale clasei ios.
?

Pentru accesul la manipulatorii care au argumente (cum sunt setw(), setfill(), etc.), este necesara includerea fisierului antet iomanip.h.

6.5 Sistemul I/O cu fisiere in C++

Desi biblioteca de streamuri din C++ reprezinta un sistem integrat pentru operatiile de intrare/iesire, lucrul cu fisiere pe disc prezinta unele particularitati care trebuie sa fie studiate separat.
Clasele care definesc streamuri care corespund unor fisiere pe disc sunt ifstream, ofstream si fstream, care sunt derivate din istream si, respectiv, ostream, deci, indirect, sunt derivate din clasa ios si au acces la toate datele si functiile membre ale acesteia. Aceste clase (ifstream, ofstream, fstream) sunt definite in fisierul antet fstream.h, care trebuie sa fie inclus atunci cand se lucreaza cu fisiere pe disc.

6.5.1 Deschiderea si inchiderea fisierelor

Pentru utilizarea unui fisier pe disc acesta trebuie sa fie asociat unui stream. Pentru aceasta se creaza mai intai un stream, iar apelul functiei open() a streamului executa asocierea acestuia cu un fisier ale carui caracteristici se transmit ca argumente ale functiei open(). Functia open() este functie membra a fiecareia dintre cele trei clase stream (ifstream, ofstream si fstream) si are prototipul:

void open(const char *file_name, int mode, int access=filebuf::openprot);

In acest prototip, file_name este numele fisierului, care poate include calea de acces. Argumentul mode defineste modurile in care poate fi deschis un fisier si are valorile definite in clasa de baza ios astfel:

class iosA public:
// ………….. enum open_mode A in=1, // desch. pt. citire out=2, // desch. pt. scriere ate=4, // desch. pt cautare app=010, // adaugare (append) trunc=020, // trunchiere nocreate=040, // er. daca nu exista fis. noreplace=0100 // er. daca fis. exista
S;
// ………………
S;

Argumentul mode este optional pentru streamuri de intrare ifstream, pentru care valoarea implicita este ios::in, si pentru streamuri de iesire ofstream, pentru care valoarea implicita este ios::out. Pentru streamuri de intrare/iesire fstream, argumentul mode trebuie sa aiba una din valorile definite in clasa ios. In argumentul mode se pot combina prin operatorul OR (SAU) doua sau mai multe din aceste valori definite.
Implicit, fisierele se deschid in mod text. Valoarea ios::binary determina deschiderea in mod binar a fisierului. Cand fisierul este deshis in mod text, au loc unele modificari de caractere, de exemplu, caracterul newline este convertit in secventa newline-carrige return. Astfel de modificari nu apar in cazul fisierelor deschise in mod binar. Orice fisier poate fi deschis in mod text sau mod binar, indiferent de felul in care au fost formatate datele.
Valoarea argumentului access determina tipul de acces la fisier. Valoarea implicita este filebuf::openprot, care specifica tipul de fisier normal (clasa filebuf este derivata din clasa streambuf).
Exemple de apeluri ale functiei open() pentru deschidere de fisiere:

ifstream input; input.open("intrare.txt"); ofstream output; output.open("iesire.txt"); fstream inout; inout.open("fisier", ios::in|ios::out);

Dupa executia unei functii de deschidere open(), starea streamului este zero, daca deschiderea s-a efectuat cu succes, si diferita de zero, daca nu s-a putut efectua deschiderea fisierului.
Deschiderea unui fisier prin apelul functiei open() poate fi evitata daca la declararea unui stream se folosesc argumente care definesc fisierul cu care se asociaza streamul. La astfel de declaratii este apelat un constructor de initializare al streamului, care executa exact aceleasi operatii de deschidere, ca si apelul functiei open(). De exemplu, se pot rescrie definirile de streamuri si fisiere asociate de mai sus astfel: ifstream input("intrare.txt"); ofstream output("iesire.txt"); fstream inout("fisier", ios::in|ios::out);

Pentru inchiderea unui fisier se apeleaza functia close(), care functie membra a claselor stream (ifstream, ofstream si fstream).

Pentru scrierea si citirea dintr-un fisier de tip text se folosesc functiile operator << si >> ale streamului asociat acelui fisier. Aceste functii operator supraincarcate pentru un anumit tip de date pot fi folosite fara nici o modificare atat pentru a scrie sau citi de la consola cat si pentru a scrie sau citi dintr-un fisier pe disc. Acest lucru este posibil deoarece clasele ifstream, ofstream si fstream sunt derivate din clasele istream, ostream si iostream respectiv, iar conversia de la un tip derivat (de exemplu, ifstream) la un tip de baza al acestuia (de exemplu, istream) este implicita. Exemplul urmator evidentiaza acest mod de operare.

? Exemplul 6.6

Programul care urmeaza creaza un fisier de inventariere “inventar.txt” care contine numele articolului, pretul unitar, numarul de bucati si valoarea totala.

void finv()A ofstream output("inventar.txt"); if (!output) cout << "Nu se poate deschide fisierul inventar.txt\n";

char buffera80i; double pret,total; int buc;

while(1)A cout << "\nArticol: "; cin.get(buffer,80); if (buffera0i == 0) break; cout << "Pret unitar: "; cin >> pret; cout << "Nr. bucati: "; cin >> buc; cin.get(); total = buc*pret; output << buffer << endl; output << pret<< endl; output << buc << endl; output << total << endl;
S output.close();
S
?

La citirea dintr-un fisier de tip text de pe disk folosind operatorul >> apar, la fel ca la citirea de la consola, anumite modificari de caractere. Pentru a evita astfel de modificari se folosesc functiile de I/O binare care vor fi prezentate in sectiunea urmatoare.

6.5.2 Operatii I/O binare cu fisiere

6.5.3 Accesul aleator la fisiere

Pentru accesul aleator la date in fisiere pe disc, sistemul I/O din C++ foloseste doi pointeri asociati fiecarui fisier: pointerul de citire (get) care specifica pozitia de unde va avea loc urmatoarea citire din fisier si pointerul de scriere (put), care specifica pozitia unde va avea loc urmatoarea scriere in fisier. Pozitia intr-un fisier este pozitia unui caracter in fisierul respectiv are valori incepand de la valoarea zero, pana la valoarea maxima a numarului de caractere continute in fisier. Dupa fiecare operatie de citire sau se scriere, pointerul corespunzator este avansat secvential in fisier in mod automat. Se poate considera un fisier ca un tablou de caractere, accesate secvential (in mod automat) sau aleator (prin modificarea pointerilor de scriere si de citire). Pentru pozitionarea intr-o pozitie dorita a unuia dintre acesti pointeri se folosesc functii membre publice ale claselor de baza istream, ostream.

Pentru accesul aleator in operatiile de iesire se pot folosi urmatoarele functii membre publice ale clasei ostream:

class ostream: public virtual ios A
// …………………. public: ostream& seekp(streampos pos); ostream& seekp(streamoff offset, seek_dir orig); streampos tellp();
// ………………
S;

Tipurile de date streamoff si streampos sunt definite in fisierul antet iostream.h, si au capacitatea de a contine cea mai mare valoare valida pe care o poate avea dimensiunea, respectiv offsetul intr-un fisier, iar seek_dir este o enumerare in clasa ios care poate lua urmatoarele valori:

class ios A
//………………... enum seek_dirA beg=0, // depl. de la inceputul fisierului cur=1, // depl. de la poz. curenta in fisier end=2 // depl. de la sfarsitul fisierului
S;
//………………..
S;

Functia seekp() cu un argument pozitioneaza pointerul de insertie a fisierului la valoarea pos, data ca argument.
Functia seekp() cu doua argumente deplaseaza pointerul de insertie al fisierului asociat streamului cu un numar de caractere egal cu valoarea offset fata de originea orig specificata ca argument.
Functia tellp() returneaza pozitia curenta de scriere in fisier, deci valoarea pointerului de scriere.

Pentru accesul aleator in operatiile de intrare se pot folosi urmatoarele functii membre publice ale clasei istream:

class istream : public virtual iosA
// ………………… public: int peek(); istream& putback(); istream& seekg(streampos pos); istream& seekg(streamoff offset, seek_dir orig); streampos tellg();
// …………………...
S;

Functiile supraincarcate seekg() cu unul si doua argumente se comporta in mod asemanator cu functiile seekp(), dar opereaza asupra pointerului de citire: functia seekg() cu un argument seteaza pointerul de citire in pozitia pos transmisa ca argument; functia seekg() cu doua argumente deplaseaza pointerul de citire al fisierului asociat streamului cu un numar de caractere egal cu valoarea offset fata de originea orig specificata ca argument.
Functia tellg() permite obtinerea pozitiei curente in fisier.
Functia peek() permite aflarea urmatorului caracter din fisier, fara sa-l extraga din streamul asociat.
Functia putback() permite introducerea inapoi in fisier a unui caracter, astfel incat acesta poate fi utilizat ulterior intr-o alta operatie de intrare.

In exemplele urmatoare se ilustreaza modul de utilizare a acestor functii de acces aleator la datele din fisiere.

? Exemplul 6.7

In functia finvers() se utilizeaza operatiile de acces aleator pentru inversarea primelor n caractere din fisierul cu numele “fisier.txt” .

int finvers(int n)A long i, j; char c1, c2; fstream fisier("fisier.txt", ios::in|ios::out|ios::binary); for(i=0;i<n;i++)A fisier.get(c1); cout<< c1;
S cout << endl;

for (i=0,j=n-1; i<j; i++,j--)A fisier.seekg(i, ios::beg); fisier.get(c1); fisier.seekg(j, ios::beg); fisier.get(c2);

fisier.seekp(i, ios::beg); fisier.put(c2); fisier.seekp(j, ios::beg); fisier.put(c1);
S fisier.seekg(0); for(i=0;i<n;i++)A fisier.get(c1); cout << c1;
S cout << endl;

fisier.close(); return 0;
S

Se presupune un fisier care contine urmatoarele caractere: 1234567890abcd... La apelul functiei finvers(10), la consola sunt afisate continutul primelor 10 pozitii din fisier inainte si dupa inversare astfel:

1234567890
0987654321

La un nou apel al functiei finvers(10), mesajele afisate la consola sunt:

0987654321
1234567890
?

6.6 Streamuri asociate cu siruri de caractere

Asa cum s-a prezentat in sectiunea precedenta, un stream poate fi asociat cu un fisier pe disc. In mod asemanator, se poate asocia un stream cu un sir de caractere in memoria principala. Clasele care construiesc streamuri in memorie (deci asociate cu siruri de caractere stocate in memoria principala) sunt descrise de clasele istrstream, ostrstream si strstream, derivate din clasele istream, ostream, iostream si sunt definite in fisierul antet strstrea.h.

Un stream de I/O asociat unui sir de caractere in memorie se poate construi ca un obiect din clasa strstream, care are doi constructori:

strstream(); strstream(char* pch, int length, int mode);

Constructorul implicit construieste un stream care foloseste un buffer intern dinamic, care initial este gol.
Constructorul cu trei argumente construieste un stream asociat unui sir de caractere in memorie, aflat la adresa pch. Argumentul length specifica numarul de caractere ale sirului. Daca acest argument are valoarea 0, atunci sirul asociat trebuie sa fie un sir terminat cu un caracter nul. Daca argumentul length are o valoare negativa, atunci se considera un sir de dimensiune infinita. Pentru o valoare pozitiva diferita de zero a argumentului length, numai primele length caractere din sir sunt asociate streamului, si streamul nu accepta caractere peste numarul de length caractere.
Argumentul mode specifica modul de creare a streamului si poate lua una din valorile ios::in, ios::out, ios::ate, ios::app, ale enumeratorului open_mode al clasei ios.
Pentru clasele istrstream si ostrstream sunt definiti constructori si functii membre asemanatoare celor din clasele corespunzatoare ifstream si ofstream.

Fie functia:

void fstr()A char* p = new chara100i; strstream ost(p, 100); ost << "123456789"; ost << "abcdef" << ends; cout << p;
S

In aceasta functie se creaza un stream ost asociat unui tablou de caractere in memorie in care se introduc mai multe caractere, ultimul fiind un caracter nul. Caracterele introduse in streamul asociat cu tabloul de caractere p sunt afisate la consola prin apelul operatorului << , iar mesajul care se obtine la executia acestei functii este: 123456789abcdef.

Din cele prezentate in acest capitol se poate intelege care este ierarhia de clase care definesc streamurile C++. In Fig. 6.1. este prezentata aceasta ierarhie. Clasa de baza ios este mostenita virtual in cele doua clase istream si ostream.


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta