Projektowanie i programowanie obiektowe (materiały do wykładu cz. VII)

Podobne dokumenty
Operacje wejścia/wyjścia (odsłona druga) - pliki

Programowanie w językach

Język C++ wykład VIII

Wykład :37 PP2_W9

Operacje na plikach. Informatyka. Standardowe strumienie wejścia i wyjścia

jest mocny, skoro da się w nim wyrazić nowe pojęcia; łatwiej przenieść go na nową platformę jest mniejszy.

Wykład II. Programowanie II - semestr II Kierunek Informatyka. dr inż. Janusz Słupik. Wydział Matematyki Stosowanej Politechniki Śląskiej

Programowanie Obiektowe i C++

Wejście wyjście strumieniowe

Operacje na plikach (niskiego poziomu) < IO.H >

C++ - [3-5] Pliki i strumienie w C++

Programowanie i struktury danych

Operacje wejścia/wyjścia odsłona pierwsza

Pliki wykład 2. Dorota Pylak

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 21 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 24

Programowanie w C++ Wykład 9. Katarzyna Grzelak. 14 maja K.Grzelak (Wykład 9) Programowanie w C++ 1 / 30

Programowanie w C++ Wykład 8. Katarzyna Grzelak. 15 kwietnia K.Grzelak (Wykład 8) Programowanie w C++ 1 / 33

Podstawy programowania skrót z wykładów:

Funkcje zawarte w bibliotece < io.h >

Pliki wykład 2. Dorota Pylak

Funkcje zawarte w bibliotece < io.h >

Klasa iostream... 1 Klasy ofstream, ifstream Struktura FILE... 8

TEMAT : KLASY POLIMORFIZM

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

Wykład 2 Operacje wejściawyjścia. Ewa Gajda

Język C++ Różnice między C a C++

1 Pierwsze kroki w C++ cz.3 2 Obsługa plików

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 20 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 32

Zajęcia nr 5 Algorytmy i wskaźniki. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie Procedurale. Pliki w języku C++

Biblioteka standardowa - operacje wejścia/wyjścia

4. Wyrzuć wyjątek jeśli zmienna ist nie istnieje bloki: try, catch i wyrzucanie wyjątku

Programowanie obiektowe

Spis treści OBSŁUGA PLIKÓW W JĘZYKU C++ Informatyka 2. Instrukcja do pracowni specjalistycznej z przedmiotu. Numer ćwiczenia INF32

Techniki programowania INP001002Wl rok akademicki 2017/18 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Wstęp do programowania obiektowego

Programowanie w C++ Wykład 5. Katarzyna Grzelak. 26 marca kwietnia K.Grzelak (Wykład 1) Programowanie w C++ 1 / 40

Pliki wykład 2 -przekazywanie strumieni do funkcji -funkcje get(char &) i getline(string)

Program dopisujący gwiazdkę na końcu pliku tekstowego o nazwie podanej przez uŝytkownika oraz wypisujący zawartość tego pliku.

Programowanie w C++ Wykład 14. Katarzyna Grzelak. 3 czerwca K.Grzelak (Wykład 14) Programowanie w C++ 1 / 27

Wstęp do Programowania 2

PARADYGMATY PROGRAMOWANIA Wykład 4

Operator przypisania. Jest czym innym niż konstruktor kopiujący!

Techniki programowania INP001002Wl rok akademicki 2018/19 semestr letni. Wykład 5. Karol Tarnowski A-1 p.

Laboratorium Systemów Operacyjnych. Ćwiczenie 4. Operacje na plikach

Wstęp do programowania obiektowego. Przekazywanie parametrów do funkcji w C++ Metody i funkcje operatorowe Strumienie: standardowe, plikowe, napisowe

Składnia C++ Programowanie Obiektowe Mateusz Cicheński

Programowanie obiektowe w języku C++ Zarządzanie procesami. dr inż. Jarosław Forenc. Przeładowanie (przeciążanie) operatorów

Wykład 1. Program przedmiotu. Programowanie Obiektowe (język C++) Literatura. Program przedmiotu c.d.:

wykład II uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C - funkcje, tablice i wskaźniki wykład II dr Jarosław Mederski Spis

Dziedziczenie & W slajdach są materiały zapożyczone z

Programowanie Obiektowe i C++

Wyjątki. Wyjątki. Bogdan Kreczmer. Katedra Cybernetyki i Robotyki Politechnika Wrocławska

dr inż. Jarosław Forenc

TEMAT : KLASY DZIEDZICZENIE

Programowanie obiektowe - Przykładowe zadania egzaminacyjne (2005/2006)

C++ - szablony. C++ - szablony. C++ - szablony. C++ - szablony. C++ - szablony. C++ - szablony

Języki programowania. Przetwarzanie plików amorficznych Konwencja języka C. Część siódma. Autorzy Tomasz Xięski Roman Simiński

Programowanie Obiektowe i C++

Języki programowania obiektowego Nieobiektowe elementy języka C++

Programowanie w C++ Wykład 11. Katarzyna Grzelak. 13 maja K.Grzelak (Wykład 11) Programowanie w C++ 1 / 30

METODY I JĘZYKI PROGRAMOWANIA PROGRAMOWANIE STRUKTURALNE. Wykład 02

Zaawansowane programowanie w języku C++ Programowanie obiektowe

Programowanie w C++ Wykład 12. Katarzyna Grzelak. 28 maja K.Grzelak (Wykład 12) Programowanie w C++ 1 / 27

utworz tworzącą w pamięci dynamicznej tablicę dwuwymiarową liczb rzeczywistych, a następnie zerującą jej wszystkie elementy,

tablica: dane_liczbowe

Wstęp do programowania. Dariusz Wardecki, wyk. X

Dla każdej operacji łącznie tworzenia danych i zapisu ich do pliku przeprowadzić pomiar czasu wykonania polecenia. Wyniki przedstawić w tabelce.

Programowanie proceduralne INP001210WL rok akademicki 2015/16 semestr letni. Wykład 6. Karol Tarnowski A-1 p.

PARADYGMATY PROGRAMOWANIA Wykład 3

wykład IV uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C, a C++. wykład IV dr Jarosław Mederski Spis Język C++ - wstęp

Języki programowania. Przetwarzanie tablic znaków. Część druga. Autorzy Tomasz Xięski Roman Simiński

wykład V uzupełnienie notatek: dr Jerzy Białkowski Programowanie C/C++ Język C++ klasy i obiekty wykład V dr Jarosław Mederski Spis Język C++ - klasy

TABLICE W JĘZYKU C/C++ typ_elementu nazwa_tablicy [wymiar_1][wymiar_2]... [wymiar_n] ;

Nowe słowa kluczowe. Komentarze. Wskaźniki typu void. class, delete, new, friend,... /* Komentarz w C i C++ */ // Komentarz w C++ (do końca wiersza)

// Potrzebne do memset oraz memcpy, czyli kopiowania bloków

Podstawy programowania

main( ) main( void ) main( int argc, char argv[ ] ) int MAX ( int liczba_1, liczba_2, liczba_3 ) źle!

Podstawy programowania w języku C++

Podstawy programowania. Wykład: 9. Łańcuchy znaków. dr Artur Bartoszewski -Podstawy programowania, sem 1 - WYKŁAD

Programowanie 2. Język C++. Wykład 3.

Tablice i struktury. czyli złożone typy danych. Programowanie Proceduralne 1

Referencje. Zasady zaliczeń. Zasady zaliczeń. Zasady zaliczeń. Zasady zaliczeń. Zaawansowane Programowanie Obiektowe. Informacje organizacyjne:

Programowanie w C++ Wykład 13. Katarzyna Grzelak. 4 czerwca K.Grzelak (Wykład 13) Programowanie w C++ 1 / 26

Pliki wykład. Dorota Pylak

Pliki wykład. Dorota Pylak

Wstęp do Programowania 2

Programowanie komputerowe. Zajęcia 1

Język C++ wykład VII. uzupełnienie notatek: dr Jerzy Białkowski. Programowanie C/C++ Język C++ wykład VII. dr Jarosław Mederski. Spis.

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

Podstawy informatyki. Informatyka stosowana - studia niestacjonarne. Grzegorz Smyk. Wydział Inżynierii Metali i Informatyki Przemysłowej

1 Wskaźniki i zmienne dynamiczne, instrukcja przed zajęciami

Informacje wstępne #include <nazwa> - derektywa procesora umożliwiająca włączenie do programu pliku o podanej nazwie. Typy danych: char, signed char

Operatory na rzecz typu TString

Wstęp do programowania obiektowego. WYKŁAD 3 Dziedziczenie Pola i funkcje statyczne Funkcje zaprzyjaźnione, this

Kurs programowania. Wykład 2. Wojciech Macyna. 17 marca 2016

PROE wykład 3 klasa string, przeciążanie funkcji, operatory. dr inż. Jacek Naruniec

Wykład VI. Programowanie. dr inż. Janusz Słupik. Gliwice, Wydział Matematyki Stosowanej Politechniki Śląskiej. c Copyright 2014 Janusz Słupik

Wprowadzenie do programowania i programowanie obiektowe

Transkrypt:

Projektowanie i programowanie obiektowe (materiały do wykładu cz. VII) Jacek Cichosz www.zssk.pwr.wroc.pl Katedra Systemów i Sieci Komputerowych Politechnika Wrocławska

Dziedziczenie 265 Klasy abstrakcyjne class Figura{ public: // Czyste funkcje wirtualne virtual void rysuj() const = 0; virtual void przesun( int, int ) = 0; ; Klasa abstrakcyjna reprezentuje abstrakcyjne pojęcie i ma sens tylko jako klasa podstawowa dla jakiejś klasy pochodnej.

Dziedziczenie 265 Klasy abstrakcyjne class Figura{ public: // Czyste funkcje wirtualne virtual void rysuj() const = 0; virtual void przesun( int, int ) = 0; ; Klasa abstrakcyjna reprezentuje abstrakcyjne pojęcie i ma sens tylko jako klasa podstawowa dla jakiejś klasy pochodnej. Klasa abstrakcyjna to taka klasa, która zawiera przynajmniej jedną czystą funkcję wirtualną.

Dziedziczenie 265 Klasy abstrakcyjne class Figura{ public: // Czyste funkcje wirtualne virtual void rysuj() const = 0; virtual void przesun( int, int ) = 0; ; Klasa abstrakcyjna reprezentuje abstrakcyjne pojęcie i ma sens tylko jako klasa podstawowa dla jakiejś klasy pochodnej. Klasa abstrakcyjna to taka klasa, która zawiera przynajmniej jedną czystą funkcję wirtualną. Nie można tworzyć żadnych obiektów takiej klasy.

Dziedziczenie 266 Czyste funkcje wirtualne Czyste funkcje wirtualne różnią się od zwykłych funkcji wirtualnych inicjatorem 0, np. class Figura{ public: virtual void rysuj() const = 0; ; Sensownej definicji funkcji wirtualnej zdeklarowanej jako czysta, można dostarczyć dopiero w klasach pochodnych. Czysta funkcja wirtualna, której nie zdefiniowano w klasie pochodnej pozostaje czystą funkcją wirtualną, a klasa pozostaje abstrakcyjna i nie można tworzyć żadnych jej obiektów.

Dziedziczenie 267 Czyste funkcje wirtualne class Figura{ public: virtual void rysuj() const = 0; virtual void przesun( int, int ) = 0; ; class Okrag : public Figura{ Punkt srodek; int promien; public: Okrag( Punkt, int ); void rysuj() const; void przesun( int, int ); ; Klasy abstrakcyjnej można użyć jedynie jako klasy podstawowej dla innej klasy.

Dziedziczenie 268 Definiowanie funkcji wirtualnych etapami Czysta funkcja wirtualna, której nie zdefiniowano w klasie pochodnej pozostaje czystą funkcją wirtualną, a klasa pochodna pozostaje. Funkcje wirtualne można definiować etapami w kolejnych klasach pochodnych. class A{ public: virtual void f() = 0; virtual void g() = 0; ; A a; // Błąd! nie można tworzyć obiektu klasy A class B : public A{ public: void f(); // Unieważnia A :: f() ; B b; // Błąd! B jest klasą abstrakcyjną class C : public B{ public: void g(); // Unieważnia A :: g() ; C c; // O.K.

Dziedziczenie 269 Biblioteka figur założenia Klasa abstrakcyjna Figura definiuje ogólne pojęcie figury dwuwymiarowej poprzez zbiór operacji jakie można na niej wykonać.

Dziedziczenie 269 Biblioteka figur założenia Klasa abstrakcyjna Figura definiuje ogólne pojęcie figury dwuwymiarowej poprzez zbiór operacji jakie można na niej wykonać. Konkretne figury: Okrag, Linia, Prostokat,... klasy potomne klasy Figura.

Dziedziczenie 269 Biblioteka figur założenia Klasa abstrakcyjna Figura definiuje ogólne pojęcie figury dwuwymiarowej poprzez zbiór operacji jakie można na niej wykonać. Konkretne figury: Okrag, Linia, Prostokat,... klasy potomne klasy Figura. Każda określona figura definiuje dla siebie reprezentację, sposób rysowania i przesuwania.

Dziedziczenie 269 Biblioteka figur założenia Klasa abstrakcyjna Figura definiuje ogólne pojęcie figury dwuwymiarowej poprzez zbiór operacji jakie można na niej wykonać. Konkretne figury: Okrag, Linia, Prostokat,... klasy potomne klasy Figura. Każda określona figura definiuje dla siebie reprezentację, sposób rysowania i przesuwania. Operacje dla każdej figury powinny być dostępne wyłączne przez interfejs dostarczany przez klasę Figura.

Dziedziczenie 269 Biblioteka figur założenia Klasa abstrakcyjna Figura definiuje ogólne pojęcie figury dwuwymiarowej poprzez zbiór operacji jakie można na niej wykonać. Konkretne figury: Okrag, Linia, Prostokat,... klasy potomne klasy Figura. Każda określona figura definiuje dla siebie reprezentację, sposób rysowania i przesuwania. Operacje dla każdej figury powinny być dostępne wyłączne przez interfejs dostarczany przez klasę Figura. Chcemy przydzielać pamięć dla obiektów figur wymaganie wirtualnego destruktora.

Dziedziczenie 270 Graficzne współrzędne ekranowe punktu struct Punkt{ short x, y; void operator += ( Punkt d ){ x += d.x; y += d.y; inline Punkt( int l, int r ) : x( l ), y( r ) { ; (0,0) y getmaxy() x (x,y) getmaxx() Funkcja void Punkt :: operator += ( Punkt d ) służy do wyznaczania współrzędnych punktu po jego przesunięciu o wektor d. Klasa Punkt w pewnych sytuacjach oznacza współrzędne punktu, np. w reprezentacji różnych figur, a w innych oznacza współrzędne wektora d = [x, y], np. w argumencie funkcji operator += ().

Dziedziczenie 271 Klasa podstawowa class Figura{ public: virtual void rysuj() const = 0; virtual void przesun( Punkt ) = 0; virtual ~Figura() = 0; ; Figura :: ~Figura(){ Rysowanie polega na wywołaniu odpowiedniej funkcji bibliotecznej. Przesuwanie o zadany wektor polega na obliczeniu nowych współrzędnych figury.

Dziedziczenie 272 Reprezentacja prostokąta class Prostokat : public Figura{ Punkt lg, pd; public: inline Prostokat( Punkt l, Punkt r ) :lg( l ), pd( r ) { void rysuj() const; void przesun( Punkt ); ~Prostokat(); ; // Rysowanie za pomocą funkcji bibliotecznej void Prostokat :: rysuj() const{ rectangle( lg.x, lg.y, pd.x, pd.y ); Prostokat :: ~Prostokat(){ //... Usuń rysunek figury z ekranu

Dziedziczenie 273 Przesunięcie prostokąta na płaszczyźnie // Wyznacz nowe położenie figury void Prostokat :: przesun( Punkt p ){ lg += p; pd += p;

Dziedziczenie 274 Reprezentacja odcinka linii class Linia : public Figura{ Punkt pocz, kon; public: inline Linia( Punkt l, Punkt r ); void rysuj() const; void przesun( Punkt ); ~Linia(); ; Linia :: Linia( Punkt l, Punkt r ) : pocz( l ), kon( r ){ void Linia :: rysuj() const{ line( pocz.x, pocz.y, kon.x, kon.y ); Linia :: ~Linia(){ // Usuń rysunek odcinka z ekranu

Dziedziczenie 275 Przesunięcie linii na płaszczyźnie // Wyznacz nowe polożenie odcinka na ekranie void Linia :: przesun(punkt p){ pocz += p; kon += p;

Dziedziczenie 276 Reprezentacja okręgu class Okrag : public Figura{ Punkt srodek; short promien; public: Okrag( Punkt s, int r ); void rysuj() const; void przesun( Punkt ); ~Okrag(); ; Okrag :: Okrag( Punkt s, int r ) : srodek(s), promien( r ){ void Okrag :: rysuj() const{ circle( srodek.x, srodek.y, promien ); Okrag :: ~Okrag(){ // Usuń rysunek okręgu z ekranu

Dziedziczenie 277 Przesunięcie okręgu na płaszczyźnie // // Wyznacz nowe położenie środka // void Okrag :: przesun( Punkt p ){ srodek += p;

Dziedziczenie 278 Program użytkowy void main(){ int driver = DETECT, mode; initgraph( &driver, &mode, "c:\\borlandc\\bgi"); if(graphresult()!= grok ){ cprintf("blad grafiki\n"); exit(1); Figura * p[] = { new Okrag( Punkt( 100, 60 ), 40 ), new Prostokat( Punkt(200, 200), Punkt(340, 400 )), new Linia( Punkt(0,0), Punkt(200, 300)); rysuj_tab(p,sizeof(p)/sizeof(p[0])); p[1]->przesun(punkt(100, 100)); for( int i = 0; i < sizeof(p)/sizeof(p[0]) ; i++ ) delete p[i]; closegraph(); void rysuj_tab( Figura * p[], int rozmiar ){ for( int i = 0; i < rozmiar ; i++ ) p[i]->rysuj();

Dziedziczenie 279 Reprezentacja ogólnego pojęcia class Koszyk{ protected: int licznik; // Licznik elementów public: int ilosc() const { return licznik; Koszyk() : licznik( 0 ) { virtual ~Koszyk() = 0; virtual int dodaj( RecordT * ) = 0; virtual int usun( RecordT * ) = 0; virtual void usun_wszystko() = 0; ; Koszyk :: ~Koszyk() {

Dziedziczenie 280 Reprezentacja pojęcia Koszyk za pomocą listy // Koszyk zrealizowany za pomocą listy class KoszykLista : public Koszyk{ // Dane potrzebne do reprezentacji listy public: KoszykLista(); // Zwolnij pamięc elementów listy ~KoszykLista(); int dodaj( RecordT * ); int usun( RecordT * ); void usun_wszystko(); ;

Dziedziczenie 281 Koszyk oparty na tablicy // Koszyk zrealizowany za pomocą tablicy class KoszykTab : public Koszyk{ // Dane potrzebne do reprezentacji tablicy public: // Utwórz tablicę o zadanym rozmiarze KoszykTab( int ); // Zwolnij pamięć elementów tablicy virtual ~KoszykTab(); virtual int dodaj( RecordT * ); virtual int usun( RecordT * ); void usun_wszystko(); ;

Dziedziczenie 282 Koszyk oparty tablicy posortowanej // Koszyk zrealizowany za pomocą uporządkowanej tablicy class KoszykSrt : public KoszykTab{ public: // Utwórz tablicę o zadanym rozmiarze KoszykSrt( int r ) : KoszykTab( r ); // Destruktor nie robi nic // Pamięć zwalnia destruktor klasy KoszykTab ~KoszykSrt() { int dodaj( RecordT * ); int usun( RecordT * ); ;

Dziedziczenie 283 Wypelnianie koszyka void robimy_zakupy( Koszyk & k ){ RecordT * rp; while( (rp = czekaj_na_wybor_klienta())!= NULL ) k.dodaj( rp ); KoszykLista list; robimy_zakupy( list ); KoszykSrt srt; robimy_zakupy( srt );

Dziedziczenie 284 Ogólna klasa do przeglądania zawartości koszyka class KoszykItr{ public: // Inicjuj przeglądanie koszyka virtual void na_poczatek() = 0; virtual void na_koniec() = 0; // Zwróć wskaźnik bieżącego elementu virtual RecordT * biezacy() = 0; virtual RecordT * nastepny() = 0; virtual RecordT * poprzedni() = 0; ;

Dziedziczenie 285 Przeglądanie zawartości koszyka listowego class KoszykListaItr : public KoszykItr{ public: KoszykListaItr( KoszykLista & ); // Inicjuj przeglądanie koszyka void na_poczatek(); void na_koniec(); // Zwróć wskaźnik bieżącego elementu RecordT * biezacy(); RecordT * nastepny(); RecordT * poprzedni(); ;

Dziedziczenie 286 Przeglądanie zawartości koszyka tablicowego class KoszykTabItr : public KoszykItr{ public: KoszykTabItr( KoszykTab & ); // Inicjuj przeglądanie koszyka void na_poczatek(); void na_koniec(); // Zwróć wskaźnik bieżącego elementu RecordT * biezacy(); RecordT * nastepny(); RecordT * poprzedni(); ;

Dziedziczenie 287 Drukowanie zawartości koszyka void drukuj_koszyk( KoszykItr & itr ){ drukuj_naglowek(); // Np. Oto twoje zakupy: RecordT * rp; while( ( rp = nastepny() )!= NULL ) drukuj_rekord( rp ); KoszykTab tab( 20 ); KoszykSrt srt( 50 ); KoszykLista list; drukuj_koszyk(koszyktabitr( tab )); drukuj_koszyk(koszyksrtitr( srt )); drukuj_koszyk(koszyklistaitr( list ));

Dziedziczenie 288 Klasy strumieniowe ios fstreambase istream ostream strstreambase ifstream istrstream ofstream iostream ostrstream fstream strstream

Dziedziczenie 289 Zakres odpowiedzialności klas strumieniowych Klasa C ios istream ostream iostream fstreambase ifstream ofstream fstream strstreambase istrstream ostrstream strstream Zakres odpowiedzialności Sterowanie formatem, stan strumienia Operacje wejściowe Operacje wyjściowe Operacje wejściowe i wyjściowe Klasa podstawowa do operacji we/wy na plikach Operacje wejściowe na plikach Operacje wyjściowe na plikach Operacje wejściowe i wyjściowe na plikach Klasa podstwowa do operacji we/wy na pamięci Operacje wejściowe na pamięci Operacje wyjściowe na pamięci Operacje wejściowe i wyjściowe na pamięci

Dziedziczenie 290 Stany strumienia Z każdym strumieniem jest związany jego stan. Zastosowanie: obsługa błędów i różnych warunków takich jak napotkanie końca strumienia. Funkcje do testowania stanu strumienia (klasa: ios). Funkcja bad() eof() fail() good() operator!() Opis Strumień jest zniszczony. Napotkano koniec strumienia. Następna operacja zakończy się niepowodzeniem. Następna operacja może się zakończyć sukcesem. Zwraca TRUE, jeśli strumień w stanie bad lub fail Zniszczony strumień oznacza, że znaki zostały zgubione.

Dziedziczenie 291 Testowanie stanu strumienia w warunku #include <iostream.h> void main(){ int liczba; while( cin >> liczba ) cout << liczba << endl; Jeśli używamy strumienia w warunku, to testujemy jego stan. Test kończy się pomyślnie (zwracana jest wartość niezerowa) tylko wtedy, gdy strumień jest w stanie good.

Dziedziczenie 292 Testowanie stanu strumienia za pomocą funkcji

Dziedziczenie 293 Ustawianie stanu strumienia

Dziedziczenie 294 Strumienie plikowe <fstream.h> Otwieranie istniejącego pliku do odczytu: ifstream wejscie( "c:\\jacek\\dane.txt" ); if(!wejscie ){ cerr << "Nie moge otworzyc pliku!" << endl; exit( 1 ); Otwieranie pliku do zapisu: ofstream wyjscie( "c:\\jacek\\wyniki.txt" ); Otwieranie pliku do zapisu i odczytu: fstream dbase( "c:\\jacek\\rekordy.dat", ios :: in ios :: out ); Zamykanie pliku realizują destruktory odpowiednich klas lub funkcja close().

Dziedziczenie 295 Nieformatowane wejście i wyjście #include <fstream.h> int main( int argc, char *argv[] ){ if( argc!= 3 ){cerr << "Skladnia: kopiuj <src> <dst>\n"; return 1; ifstream src( argv[1] ); if(!src ){ cerr << "Nie mozna otworzyc pliku: " << argv[1] << endl; return 1; ofstream dst(argv[2]); if(!src ){ cerr << "Nie mozna otworzyc pliku: " << argv[2] << endl; return 1; char c; while( src.get( c ) ) dst.put( c ); if(!src.eof() dst.bad() ){ cerr << "Powazny blad!\n"; return 2; return 0;

Dziedziczenie 296 Wprowadzanie tekstów Rozwiązanie ryzykowne! Co będzie, gdy napis przekroczy 17 znaków? #define DLUG 18 #include <iostream.h> void main(){ char buf[dlug]; cin >> buf; cout << buf;

Dziedziczenie 296 Wprowadzanie tekstów Rozwiązanie ryzykowne! Co będzie, gdy napis przekroczy 17 znaków? #define DLUG 18 #include <iostream.h> void main(){ char buf[dlug]; cin >> buf; cout << buf; Bezpieczne wprowadzanie linii tekstu za pomocą funkcji get(). cin.get( buf, DLUG, \n );

Dziedziczenie 297 Wprowadzanie tekstu za pomocą get() Deklaracja:

Dziedziczenie 297 Wprowadzanie tekstu za pomocą get() Deklaracja:istream & get( char * gdzie, int ile, int = \n );

Dziedziczenie 297 Wprowadzanie tekstu za pomocą get() Deklaracja:istream & get( char * gdzie, int ile, int = \n ); Wczytuje zadaną liczbę znaków, chyba że zostanie napotkany znak terminatora (domyślnie: \n ).

Dziedziczenie 297 Wprowadzanie tekstu za pomocą get() Deklaracja:istream & get( char * gdzie, int ile, int = \n ); Wczytuje zadaną liczbę znaków, chyba że zostanie napotkany znak terminatora (domyślnie: \n ). Jeśli na wejściu pozostanie terminator, to będzie on pierwszym nie przeczytanym znakiem strumienia. Dzięki temu można sprawdzać przepełnienie bufora: #include <iostream.h> void main(){ char buf[dlug]; cin.get( buf, DLUG, \n ); char c; if( cin.get( c ) && c!= \n ) cerr << "Napis przekroczyl dlugosc bufora" << endl;

Dziedziczenie 298 Ustalanie i odczyt pozycji strumienia Funkcja Opis ostream& ostream::seekp( streampos ); Ustaw pozycję ostream& ostream::seekp( streamoff, ios::seekdir ); Ustaw pozycję streampos ostream::tellp(); Odczyt pozycji istream& istream::seekg( streampos ); Ustaw pozycję istream& istream::seekg( streamoff, ios::seekdir ); Ustaw pozycję streampos istream::tellg(); Odczyt pozycji g oznacza pozycję odczytu znaku, a p pozycję zapisu. ios :: seekdir oznacza bieżącą pozycję, względem której należy ustawiać nową pozycję strumienia:

Dziedziczenie 298 Ustalanie i odczyt pozycji strumienia Funkcja Opis ostream& ostream::seekp( streampos ); Ustaw pozycję ostream& ostream::seekp( streamoff, ios::seekdir ); Ustaw pozycję streampos ostream::tellp(); Odczyt pozycji istream& istream::seekg( streampos ); Ustaw pozycję istream& istream::seekg( streamoff, ios::seekdir ); Ustaw pozycję streampos istream::tellg(); Odczyt pozycji g oznacza pozycję odczytu znaku, a p pozycję zapisu. ios :: seekdir oznacza bieżącą pozycję, względem której należy ustawiać nową pozycję strumienia:ios :: beg początek pliku

Dziedziczenie 298 Ustalanie i odczyt pozycji strumienia Funkcja Opis ostream& ostream::seekp( streampos ); Ustaw pozycję ostream& ostream::seekp( streamoff, ios::seekdir ); Ustaw pozycję streampos ostream::tellp(); Odczyt pozycji istream& istream::seekg( streampos ); Ustaw pozycję istream& istream::seekg( streamoff, ios::seekdir ); Ustaw pozycję streampos istream::tellg(); Odczyt pozycji g oznacza pozycję odczytu znaku, a p pozycję zapisu. ios :: seekdir oznacza bieżącą pozycję, względem której należy ustawiać nową pozycję strumienia:ios :: beg początek pliku, ios :: cur bieżąca pozycja

Dziedziczenie 298 Ustalanie i odczyt pozycji strumienia Funkcja Opis ostream& ostream::seekp( streampos ); Ustaw pozycję ostream& ostream::seekp( streamoff, ios::seekdir ); Ustaw pozycję streampos ostream::tellp(); Odczyt pozycji istream& istream::seekg( streampos ); Ustaw pozycję istream& istream::seekg( streamoff, ios::seekdir ); Ustaw pozycję streampos istream::tellg(); Odczyt pozycji g oznacza pozycję odczytu znaku, a p pozycję zapisu. ios :: seekdir oznacza bieżącą pozycję, względem której należy ustawiać nową pozycję strumienia:ios :: beg początek pliku, ios :: cur bieżąca pozycja, ios :: end koniec pliku.

Dziedziczenie 299 Binarny odczyt i zapis do pliku Klasę RecTbl poszerzamy o dwie operacje: odczyt_bin i zapis_bin. class RecTbl{ public: // Zapis bazy w formacie binarnym ostream & zapis_bin( ostream & ) const; // Odczyt bazy w formacie binarnym istream & odczyt_bin( istream & ); //... Pozostałe deklaracje private: int rozmiar; int licznik; OsobaInfo * tab; ;

Dziedziczenie 300 Operacja odczytu z pliku binarnego istream & RecTbl :: odczyt_bin( istream & is ){ // Zbadaj rozmiar pliku is.seekg( 0, ios :: end ); // Przesuń wskaźnik na koniec int bajty = is.tellg(); // Odczytaj pozycję // Czy wystarczy miejsca na dane if( bajty / sizeof(osobainfo) > rozmiar ){ // Trzeba powiększyc rozmiar bazy is.seekg( 0, ios :: beg ); // Przesuń wskaźnik na początek is.read( (char *)tab, bajty ); // Wczytaj całą tablicę licznik = bajty / sizeof(osobainfo); return is;

Dziedziczenie 301 Operacja zapisu do pliku binarnego Zapis do pliku binarnego wszystkich rekordów bazy ostream & RecTbl :: zapis_bin( ostream & os ) const{ if( licznik > 0 ) os.write( (char *)tab, licznik*sizeof(osobainfo)); return os; Funkcja do nieformatowanego odczytu: istream & istream :: read( char* gdzie, int ile); Funkcja do nieformatowanego zapisu: ostream & ostream :: write( char* buf, int ile);

Dziedziczenie 302 Przykładowy program void main( int argc, char *argv[] ){ if( --argc ){ ifstream plik_we(*++argv, ios::in ios::binary ); if(!plik_we ){ cerr << "Nie moge otworzyc pliku: " << *argv << endl; exit( 1 ); RecTbl tbl(100); tbl.odczyt_bin( plik_we ); plik_we.close(); tbl.dodaj("abacki", 6759015 ); // Zapis binarny do pliku ofstream plik_wy( *argv, ios::out ios::binary ); if(!plik_wy ){ cerr << "Nie moge otworzyc pliku: " << *argv << endl; exit( 1 ); tbl.zapis_bin( plik_wy );

Dziedziczenie 303 Strumienie napisowe <strstrea.h> Strumień można związać z tablicą znaków w pamięci głównej: #define ROZM 512 char buf[rozm]; ostrstream strwyj( buf, ROZM ); strwyj << "2 + 2 = " << 4; Jeśli nastąpi przepełnienie bufora, strumień automatycznie przejdzie w stan fail. Można użyć taki strumień do formatowania tekstu, którego nie trzeba drukować od razu.

Dziedziczenie 304 Strumienie napisowe przykład #include <strstrea.h> const int ROZM = 256; void main( int argc, char * argv[] ){ char buf[rozm]; ostrstream strwy( buf, ROZM ); strwy << "Ten program nazywa sie: " << *argv++ << " i ma " << --argc << " argumentow" << endl << "Argumenty programu:" << endl; while( argc-- ) strwy << *argv++ << endl; strwy << \0 ; cout << buf << endl;

Dziedziczenie 305 Operatory we/wy dla typów użytkownika class Zesp{ double re, im; public: inline Zesp( double r, double i = 0.0 ) : re( r ), im( i ) { //... // Operator wprowadzania friend istream & operator >> ( istream &, Zesp & ); // Operator wyprowadzania friend ostream & operator << ( ostream &, Zesp & ); ;

Dziedziczenie 306 Reprezentacja liczby zespolonej Liczba zespolona z niezerową częścią urojoną: ( liczba_rzeczywista, liczba rzeczywista ), np. (2.7, 90.5) Liczba zespolona z zerową częścią urojoną może być reprezentowana jak wyżej lub: (liczba_rzeczywista), np. (34.98) lub liczba_rzeczywista, np. 34.98 Przykład poprawnego strumienia wejściowego: 34.56 0 25.78 ( 56.898, 6.5 ) (12.8) 45.21

Dziedziczenie 307 Operator wprowadzania dla typu: Zesp istream & operator >> ( istream & is, Zesp & z){ double r, i = 0.0; char c = \0 ; is >> c; if( c == ( ){ is >> r >> c; if( c ==, ) is >> i >> c; if( c!= ) ) is.clear( ios :: badbit ); else{ is.putback( c ); //Zwraca znak z powrotem do strumienia is >> r; if( is ) z = Zesp( r, i ); return is;

Dziedziczenie 308 Operator wyprowadzania dla: Zesp ostream & operator << ( ostream & os, Zesp & z){ if( z.im!= 0.0 ) os << ( << z.re <<, << z.im << ) ; else os << z.re; return os; void main(){ Zesp z( 0.0 ); while ( cin >> z ) cout << z << endl;

Dziedziczenie 309 Operatory we/wy dla klasy OsobaInfo class OsobaInfo{ friend class RecTbl; // Operator wyprowadzania friend ostream & operator << ( ostream &, OsobaInfo & ); // Operator wprowadzania friend istream & operator >> ( istream &, OsobaInfo & ); //... Pozostałe deklaracje ; // Prosta wersja operatora wprowadzania istream & operator >> ( istream & is, OsobaInfo & oi ){ is >> oi.nazwisko >> oi.tel; return is; // Operator wyprowadzania ostream & operator << ( ostream & os, OsobaInfo & oi ){ os << oi.nazwisko << << oi.tel; return os;

Dziedziczenie 310 Operator >> dla klasy OsobaInfo istream & operator >> ( istream & is, OsobaInfo & oi ){ char c; // Pomiń białe znaki while( is.get( c ) ) if(!isspace( c ) ){ is.putback( c ); break; char * p = oi.nazwisko; int i; // Nazwisko może zawierać tylko litery i znak myślnika - for( i = 0 ; i < DLUG_NAZW && is.get( c ) ; i++, p++ ) if( isalpha( c ) c == - ) *p = c; else break; if( i == DLUG_NAZW ) ++p; *p = \0 ; while( c!= \n &&!isdigit( c ) && is.get( c )) ; if( isdigit( c )){ is.putback( c ); is >> oi.tel; return is;

Dziedziczenie 311 Operator >> dla klasy RecTbl Operator >> zrealizowano jako funkcję zewnętrzną. istream & operator >> ( istream & is, RecTbl & tab ){ char buf[dlug_nazw + 1]; Tele tel; while( is >> buf >> tel ) tab.dodaj( buf, tel ); return is; Użycie w programie głównym. RecTbl tab( 100 ); ifstream plik( "c:\\jacek\\telefony.txt" ); plik >> tab;

Dziedziczenie 312 Operator << dla klasy RecTbl Operator << zrealizowano jako funkcję zewnętrzną. ostream & operator << ( ostream & os, const RecTbl & tab ){ RecTbl :: Itr b = tab.beg(); RecTbl :: Itr e = tab.end(); while( b!= e ){ os << *b << endl; ++b; return os; Wyprowadzenie nazwisk na ekran RecTbl tab(100); //... Wypełnij tablicę nazwiskami cout << tab;

Dziedziczenie 313 Indeks c J. Cichosz Start Projektowanie i programowanie obiektowe