Limbajul C++ si oop abc-doar



Yüklə 1,36 Mb.
səhifə7/18
tarix12.09.2018
ölçüsü1,36 Mb.
#81721
1   2   3   4   5   6   7   8   9   10   ...   18

#include

main()

{ FILE *fila1;

char buf[180];

fila1=fopen("TEXTC.txt","r");

rewind(fila1);

while ( ! feof(fila1) )

{ fread(buf,180,1,fila1);

printf("%s \n",buf);

}

fclose(fila1);

getch();

return 0;

}

In exemplul de mai sus,fila TEXYC.txt este o fila oarecare in care am

introdus un text exemplificativ si pe care am arhivat-o in acelasi direc-

tor cu aplicatia.Pentru a citi o fila situata in alt director,se va uti-

liza calea completa de acces (gen "C:\\calea de acces\numele filei" ).

Am utilizat stream-ul FILE si un tampon de memorie de tip char.


-41-

Solutia este simpla si eficienta pentru filele de tip text care nu

contin decat date de tip text si nu necesita nici un fel de prelucrare.

In C stream-ul este un tampon de memorie simplu,in care datele vor fi

preluate caracter cu caracter.

Solutia prezinta si o serie de inconveniente.Astfel,daca fila preluata

contine si date de tip numeric sau de tip data calendaristica,functia

printf() nu va putea prelua aceste date.Astfel,o simpla scrisoare datata

poate bulversa "programul de citire".Se pot adauga o serie intreaga de

IF -uri in care sa se trateze toate variantele posibile,dar aplicatia va

contine un numar mare de coduri inutile si va fi destul de laborioasa.

C++ spre deosebire de C utilizeaza stream-uri organizate sub forma

de obiecte.Pe langa tamponul de memorie utilizat pentru preluarea datelor,

streamu-urile din C++ contin si o serie de metode proprii,operatori de

preluare sau postare a datelor etc.Ca rezultat,stream-urile I/O din C++

pot accepta toate tipurile standard de date din C++,fara nici o alta

operatie de conversie si contin constructorul,destructorul si functiile

necesare pentru alocare si dealocarea memoriei.Astfel,pentru operatiile

de intrare/iesire(I/O),C++ contine o biblioteca specializata denumita

"iostrem" in care sunt definite stream-uri specializate pentru fiecare

tip de operatie.Pentru operatiile de preluare a datelor sunt definite

clasele istream,ifstream si istrstream din care se pot deriva sub forma

de obiecte streamu-urile cu care se va lucra in program.

Istream este destinat pentru operatii de intrare secventiale sau aleatorii

si contine constructorul istream(),destructorul ~istream() si metodele:

ipfx(),isfx(),get(),getline(),read(),ignore(),peek(),gcount(),eatwhite(),

putback(),sync(),seekg(),tellg() precum si operatorul >>.

Ifstream este o varianta asemenatoare si este specializat pentru operatii-

le de preluare a filelor de pe unitatea de disc (C:).Contine constructorul

ifstream(),destructorul ~ifstream(),metodele: open(),close(),setbuf(),

setmode(),attach(),rdbuf(),fd() si is_open().

Istrstream este specializat pentru operatii cu date structurate sub forma

de arii de caractere.Pentru a construi un astfel de obiect(stream) trebuie

alocata o arie de date de tip caracter ce va fi utilizata pe post de

tampon pentru preluarea datelor (trebuiesc specificate coordonatele ariei)

Contine constructorul istrstream(),destructorul ~istrstream,metodele:

rdbuf() si str().

Toate cele trei tipuri de stream-uri se utilizeaza pentru acelasi scop,

dar contin un grup diferit de metode proprii prin care pot sa actioneze

specializat asupra datelor din filele preluate.In functie de necesitati,

se va utiliza obiectul care are metodele cele mai adecvate.

In mod similar,pentru operatiile de iesire a datelor exista trei tipuri

de clase specializate: ostream,ofstream si ostrstream,din care se pot de-

riva obiecte specializate:

Ostream este obiectul standardizat pentru operatii succesive sau aleatorii

de iesire a datelor.Are atasat un obiect derivat din clasa streambuf cu

care lucreaza sincron.Obiectul derivat din ostrem realizeaza formatul iar

cel derivat din streambuf realizeaza operatiile de nivel inferior (bit cu

bit).Contine constructorul ostrem(),destructorul ~ostream() si metodele:

opfx(),osfx(),put(),write(),flush(),seekp(),tellp() precum si operatorul

de export a datelor <<.Operatorul "<<" este supraincarcat astfel incat

este similar cu cel utilizat impreuna cu "cout".


-42-

Ofstream este specializat pentru a scrie file pe disc.Contine constructo-

rul ofstream(),destructorul ~ofstream(),metodele: open(),close(),setbuf(),

setmode(),attach(),rdbuf(),fd() si is_open().

Ostrstream scrie datele sub forma de arii de caractere.Pentru a preciza

formatul se va aloca o arie de caractere utilizata ca sablon la scrierea

datelor.Obiectul lucreaza sincron cu un obiect de tip strstreambuf,care

utilizeaza un pointer pentru a avansa pas cu pas dupa scrierea fiecarei

arii.Contine constructorul ostrstream(),destructorul ~ostrstream() si

metodele: pcount(),rdbuf() si str().

Exista si stream-uri specializate atat pentru operatii de intrare cat

si pentru operatii de iesire.Aceste stream-uri acumuleaza toate metodele,

de la ambele tipuri de stream-uri si pot fi utilizate pentru ambele tipuri

de operatii.Sunt cele mai practice si cele mai frecvent utilizate (chiar

daca ocupa putin mai multa memorie).Cele doua tipuri de stream-uri care

executa atat intrari cat si iesiri sunt: fstream si strstream.

Fstream executa orice operatie de intrare iesire.Utilizeaza pe post

de tampon un obiect de tip filebuf. Contine: constructor,destructor si

metodele: open(),close(),setmode(),attach(),fd() si is_open().Este cel

mai prectic si cel mai usor de utilizat.

EXEMPLU: (vezi si cplus33.cpp )

#include

#include

main()

{ fstream fila1("TEXTC.txt",ios::in);

char buf[180];

while ( ! fila1.eof() )

{ fila1.getline(buf,200);

cout << "\n" << buf;

}

fila1.close();

getch();

return 0;

}

Observati ca este la fel de usor de editat ca si exemplul scris in C.In

plus,prezinta o serie de avantaje.Metoda cout si operatrorul << vor

prelua din fila orice tip de date (inclusiv float,double,long,date etc.).

Nu mai este necesara fila header "stdio.h".Obiectul derivat contine si

toate metodele necesare pentru preluarea datelor.Daca nu se vor mai

executa nici un fel de operatii asupra filei,corect este sa apelam si

destructorul ~fila1() pentru a elibera complet memoria de operare.

Pentru declararea obiectului de tip fstream am utilizat numele filei

ce urmeaza sa fie alocata in tamponul de memorie si modul in care urmeaza

sa fie utilizata fila respectiva.Pentru formarea obiectului am apelat

direct constructorul (odata cu declararea obiectului).

Constructorul fstream() are urmatoarea forma generala:

fstream ( const char* szName,int nMode,int nProt=filebuf::openprot); unde

szName -contine calea de acces la fisier si numele filei care urmeaza

sa fie deschisa.Daca fila este in acelasi director,se poate

utiliza doar numele fieli si extensia (ca in exemplu).

nMode -sunt enumeratori ai obiectului ios.Se pot combina prin opera-

torul binar OR.Ios este ancestorul tuturor stream-urilor I/O.


-43-

Parametrul nMode accepta urmatoarele valori:

ios::app -fiecare byte nou scris in fila va fi adaugat la sfarsitul

filei (append) chiar daca pozitia cursorului a fost mo-

dificata cu o alta functie

ios::ate -primul byte nou va fi scris la sfarsitul filei,dar urmatorii

se vor scrie la pozitia curenta.Daca se deplaseaza cursorul

cu ostream::seekp fila poate fi suprascrisa

ios::in -este operatorul pentru input.Suprascrie toate datele

ios::out -este operatorul pentru output.Permite citirea datelor

ios::trunc -sterge toate datele dar pastreaza fila (o trunchiaza)

ios::nocreate -returneaza eroare daca fila precizata nu exista

ios::noreplace -returneaza eroare daca exista fila precizata

ios::binary -deschide fila in modul binar (citeste biti in loc de

caractere ASCII -implicit fila este deschisa in mod text)
nProt -este specificatorul pentru modul de protectie.Accepta valorile:

filebuf::openprot -este valoarea implicita a sistemului de operare

filebuf::sh_none -nu permite partajarea filei (no sharing)

filebuf::sh_read -permite partajarea doar pentru citirea datelor

filebuf::write -permite partajarea filei pentru scriere

-daca nu se specifica se utilizeaza valoarea implicita

Obiectul de tip fstream contine inca doi constructori supraincarcati,care

pot fi utilizati optional,in anumite conditii.Primul astfel de constructor

are formula generala: fstream (filedesc fd);

unde: -fd este un descriptor al filei ce urmeaza sa fie returnat de catre

o functie de genul _open() sau _sopen()

Al doilea constructor optional are formula generala:

fstream(filedesc fd,char*pch,int nLength);

unde: -fd este ca mai sus

-pch este pointerul spre o arie de date de lungimea nLength alocata

anterior (va fi utilizata pe post de tampon,daca are valoarea NULL

stream-ul rezultat va fi netamponat)

-nLength este lungimea in bytes a ariei rezervate pentru tampon

Dupa cum se observa,nu exista o singura solutie ci un numar oarecare

de solutii alternative.La prima vedere pare destul de complicat si confuz,

dar de fapt este foarte simplu.Stream-ul pentru operatiile I/O se utili-

zeaza la fel ca orice alt obiect.Se declara tipul de data,se apeleaza

constructorul,apoi se apeleaza metodele obiectului.Nu mai sunt necesare

alte functii auxiliare sau alte file header si biblioteci.Obictul contine

toate functiile necesare.

Pentru a intelege mecanismul de mostenire a metodelor fiecarui stream,

este utila urmatoarea schema:

|- istream -------| |-fstream

ios- -iostream---|-strstream

|-ostream---------| |-stdiostream

Se observa clasa ios care este ancestorul comun.Din istream deriva toate

stream-urile de intrare a datelor iar din ostream deriva cele de iesire a

datelor.Stream-urile mixte,mostenesc atat clasa istream cat si clasa

ostream,precum si clasa ancestoare ios.Ca rezultat,stream-urile mixte

sunt cele mai complexe si pot utiliza toate metodele ancestorilor.

In exemplul urmator,fstream mediaza toate operatiile I/O:


-44-

EXEMPLU: ( vezi si cplus34.cpp )

#include

#include

main()

{ float numar=345.6789;

fstream scrie1("TEXTS.txt",ios::out);

scrie1 << "Text introdus in fila specificata: ";

scrie1 << "\n";

scrie1 << "\n Primul rand din textul introdus...";

scrie1 << "\n numarul este: " << numar <<" etc. ";

scrie1.close();

fstream fila1("TEXTS.txt",ios::in);

char buf[180];

while ( ! fila1.eof() )

{ fila1.getline(buf,200);

cout << "\n" << buf; }

getch();

return 0;

}

Din exemplul de mai sus se observa ca am utilizat clasa fstream atat

pentru obiectul scrie1,care este stream-ul de output,cat si pentru obiect-

ul file1,care este stram-ul de input.Dupa ce am deschis fila pentru scriere

datele se pot introduce pur si simplu cu operatorul << care va transfera

datele in stream.Este foarte important ca dupa epuizarea trensferului sa

se inchida fila cu functia close().In caz contrar,toate operatiile urma-

toare se vor desfasura tot in interiorul stream-ului de output.Apoi am

derivat un obiect pentru iesirea datelor si am transferat datele preluate

din fila spre ecran.Observati ca fila scrisa contine atat date de tip

text cat si valoarea numarica de tip float (numar).Operatiile cu text si

valori numrice se efectueaza extrem de usor,cu aceleasi functii si cu

ajutorul acelorasi operatori.Pentru unele operatii matematice se utili-

zeaza si o serie de manipulatori.In acest caz,va trebui incarcata in

etapa de precompilare si fila iomanip.h ( cu #include ).

Pentru practica curenta si pentru incepatori,se recomanda clasa fstream

si un numar cat mai limitat de operatii de intrare/iesire,pentru a evita

eventualele erori si/sau exceptii,care pot deranja organizarea datelor

de pe disc.Daca nu a-ti inteles perfect sistemul de apelare a metodelor

si a functiilor,este mai bine sa utilizati doar solutii standardizate si

verificate anterior.Nu toate versiunile de program contin si descrierea

claselor I/O.In rezumat,metodele acestor clase sunt:

ipfx ( int need = 0 ); verifica conditia de eroare inainte de extractie

isfx () ; -este apelata dupa operatia de extractie (input suffix)

get() -are urmatoarele variante supraincarcate:

int get(); &

istream& get (char *pch,int nCount,char delim= '\n');

istream& get (unsigned char* puch,int nCount,char delim='\n');

istream& get (signed char* psch,int nCount,char delim='\n');

istream& get (char& rch);

istream& get (unsigned char& ruch);

istream& get (signed char& rsch);

istream& get (streambuf& rsb,char delim='\n');


-45-

unde: pch,puch,psch sunt pointeri spre arii de caractere

nCount este numarul maxim de caractere

delim este caracterul utilizat ca delimitator (capatul de rand)

rch,ruch,rsch este un pointer spre un caracter (referinta)

rsb este un pointer spre un obiect de tip streambuf

-in toate variantele,get() extrage caractere din stream pana ce intalne-

ste delimitatorul specificat prin delim.

getline() - are urmatoarele variante supraincarcate

istream& getline(char *pch,int nCount,char delim='\n');

istream& getline( unsigned char* puch,int nCount,char delim='\n');

istream& getline( signed char* psch,int nCount,char delim= '\n');

-la fel ca si get() extrage caractere din stream

read() -are urmatoarele variante supraincarcate

istream& read(char* pch,int nCount);

istream& read(unsigned char* puch,int nCount);

istream& read(signed char* psch,int nCount);

-functia read() extrage nCount date din stream

ignore( int nCount = 1,int delim = EOF); extrage si sterge caractere

peek() -returneaza caracterul imediat urmator,fara sa-l extraga din stream

int gcount() const -numara caracterele extrase la ultima operatie

eatwhite() -sterge spatiul gol de la inceputul streamu-ului

putback (char ch) -repune in stream ultimul caracter extras

int sync() -sincronizeaza tamponul intern cu sursa externa de caractere

seekg() -are urmatoarele variante supraincarcate:

istream& seekg( streampos pos);

istream& seekg( streamoff off,ios::seek_dir dir);

unde : pos si off sunt de tip long

dir specifica directia de deplasare si poate fi:

ios::beg -cauta de la inceputul stream-ului

ios::cur -cauta de la pozitia cursorului

ios::end -cauta de la sfarsitul stream=ului

-modifica pozitia pointer-ului pentru functia get()

tellg() -citeste valoarea pointerului get.

Operatorul >> este supraincarcat pentru toate tipurile char,numerice si

respectiv streambuf*,istream& si ios&.

open(const char* szName,int nMode=ios::in,int nProt=filebuf::openprot);

-a fost descrisa impreuna cu constructorul pentru fstream,la exemplul

dela pagina 42.Metoda deschide o fila si ataseaza continutul in tamponul

intern al stream-ului.

close() -inchide stream-ul deschis anterior.

streambuf* setbuf( char* pch,int nLength); -ataseaza aria de memorie

specificata in tamponul intern de memorie al stream-ului

int setmode(int nMode = filebuf::text); seteaza modul text sau modul

binar pentru tamponul stream-ului.Accepta valorile : filebuf::text si

respectiv filebuf::binary.Se poate apela numai dupa ce fila a fost

deschisa

attach(filedesc fd) -ataseaza fila specificata in tamponul streamului

filebuf* rdbuf() const; returneaza un pointer spre tamponul intern

filedesc fd() const -returneaza descriptorul filei

int is_open() const -returneaza nonzero daca streamul este asociat la o

fila identificata prin descriptorul fd.In caz contrar returneaza 0.


-46-

char* str() -returneaza un pointer catre aria de caractere din stream

opfx() - verifica conditiile de eroare inainte de insertia datelor

osfx() - este apelat dupa insertie pentru a elibera tamponul intern

put(char ch) - insera un singur caracter in stream

write() -are supraincarcate urmatoarele variante:

ostream& write(const char* pch,int nCount);

ostream& write(const unsigned char* puch,int nCount);

ostream& write(const signed char* psch,int nCount);

unde : pch,puch,psch sunt pointeri spre arii de caractere

nCount este numarul de caractere ce vor fi scrise

-insera in stream o serie de bytes (nCount bytes)

flush() - elibereaza tamponul intern (sterge toate datele)

seekp( stream pos); sau seekp( stream off,ios::seek_dir dir)

-este la fel ca seekg() (vezi pagina anterioara),adica deplaseaza

pointerul de insertie pentru functia put()

streampos tellp() -citeste valoarea pointerului pentru functia put()

operatorul << este operatorul de insertie si este supraincarcat la fel

ca si cel de extractie pentru tipurile char,numerice...etc.

pcount() - returneaza numarul de bytes arhivati in tamponul intern

CONSTRUCTORII SI DESTRUCTORII

Unele stream-uri au supraincarcati mai multi constructori.Expresiile

generale sunt:

ISTREAM

istream( streambuf* psb) si respectiv destructorul ~istream()

IFSTREAM

ifstream();

ifstream( const char* szName,int nMode = ios::in,

int nProt=filebuf::openprot);

ifstream( filedesc fd);

ifstream( filedesc fd,char* pch,int nLength);

si respectiv destructorul implicit ~ifstream();

ISTRSTREAM

istrstream (char* psz);

istrstream (char* pch,int nLength);

si destructorul ~istrstream();

OSTREAM

ostream (streambuf* psb); si destructorul ~ostream();

OFSTREAM

ofsteam();

ofstream(const char* szName,int nMode=ios::out,

int nProt=filebuf::openprot);

ofstream( filedesc fd);

ofstream( filedesc fd,char* pch,int nLength);

si respectiv destructorul ~ofstream();

OSTRSTREAM

ostrstream();

ostrstream (char* pch,int nLength,int nMode= ios::out);

si destructorul ~ostrstream();

Pentru stream-urile mixte,constructorul este identic cu ifstream sau

ofstream,respectiv cu istrstream/ostrestream (in functie obiectul care

va fi derivat din clasa de baza).


-47-

In cazul in care urmeaza sa utilizati frecvent in programare aceste

clase de obiecte,este bine sa desenati fiecare clasa,impreuna cu membrii

si metodele sale,pe cate o plansa mare,afisata pe perete:

EXEMPLU: class istrstream

{ istrstream( char* pch,int nLength);

~istrstream();

public:

strstreambuf* rdbuf() const;

char* str();

}

Se observa constructorul,destructorul si cele doua metode.In momentul

in care declarati un stream,sau depanati o aplicatie,puteti utiliza

plansa pentru a va orienta rapid asupra metodelor sau asupra tipului de

Yüklə 1,36 Mb.

Dostları ilə paylaş:
1   2   3   4   5   6   7   8   9   10   ...   18




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