You are on page 1of 13

Programowanie obiektowe

Temat: Koder-dekoder

1. Wstp:.....................................................................................................................................2 1.1 Cel projektu.......................................................................................................................2 1.2 Instrukcja...........................................................................................................................2 2. Opis klas..................................................................................................................................4 2.1 Hierarchia klas..................................................................................................................4 2.1.1 Koder_dekoder...........................................................................................................4 1

2.1.2 Liczba.........................................................................................................................5 2.1.3 Slowem.......................................................................................................................5 2.1.4 Delta...........................................................................................................................5 3. Listing kodu............................................................................................................................5 3.1.1 koder_dekoder.h.............................................................................................................5 3.2.1 Liczba.h..........................................................................................................................5 3.3.1 Sowem.h........................................................................................................................7 3.3.2 Sowem.cpp....................................................................................................................7 3.4.1 Delta.h............................................................................................................................7 3.4.2 Delta.cpp........................................................................................................................8 3.5.1 ChangedNameDlg.h.......................................................................................................8 3.5.2 ChangedNameDlg.cpp...................................................................................................9 3.6 UWAGA!........................................................................................................................12 4. Algorytmy.............................................................................................................................12 4.1 Kodowanie liczb............................................................................................................12 4.2 Kodowanie sowem.........................................................................................................12 4.3 Kodowanie Delta.............................................................................................................13 5.Uwagi i wnioski.....................................................................................................................13

1. Wstp:
1.1 Cel projektu
Celem projektu byo oprogramowanie kodera/dekodera. Dla wygody zdecydowaem si na kodowanie plikw tekstowych.

1.2 Instrukcja

Rys 1.1 Gwny ekran programu.

Po wciniciu tego przycisku otworzy nam si okno wyboru pliku tekstowego: Przycisk "Plik wyjciowy" dziaa analogicznie. Tutaj wybieramy interesujcy nas algorytm kodowania, pierwsze dwie funkcje s oczywiste, a trzecia jest to kodowanie, w ktrym zakodowana warto zaley od poprzedniego znaku (a pierwszy znak pozostaje bez zmian). Nastpnie wybieramy, czy chcemy kodowa, czy dekodowa.
Rys 1.3 Opcje wyboru

Okna, w ktre wpisujemy wartoci, zalenie od algorytmu kodowania. W pierwszym wpisujemy liczb z zakresu od 1-30, ktr chcemy kodowa, jeli wybralimy pierwsz funkcj, a w drugim sowo, jeli wybralimy funkcj drug. Okna te staj si aktywne bd nie-aktywne zalenie od wybranego algorytmu.

Wcinicie przycisku "OK" wywouje wybran przez nas funkcj, a przycisk "Cancel" wycza program nie wykonujc adnego dziaania.

2. Opis klas
2.1 Hierarchia klas

Rys 2.1 Hierarchia klas wygenerowana przez Microsoft Visual Studio 2008 Class Diagram

2.1.1 Koder_dekoder
Klasa abstrakcyjna zawierajca w sobie pole typu fstream, oraz 3 metody: -koduj: funkcja kodujca -dekoduj: funkcja dekodujca -zapisz: funkcja zapisu do pliku Wszystkie te funkcje s oczywicie wirtualne.

2.1.2 Liczba
Klasa pochodna klasy koder_dekoder, zawiera dwa pola, jedno typu int, a drugie typu string, oraz 4 metody, z ktrych tylko jedna jest dla nas "nowa", pozostae s po prostu polimorficznymi wersjami tych z klasy abstrakcyjnej koder_dekoder. Dodatkow funkcj jest konstruktor. Zdecydowaem si na nie tworzenie destruktorw ze wzgldu na brak jakiejkolwiek dynamicznej alokacji w ciele obiektw, a tym samym nie widziaem sensu tworzenia destruktora, w kocu co miaby on w tym wypadku robi?

2.1.3 Slowem
Klasa pochodna klasy Liczba (a tym samym te pochodna klasy koder_dekoder). Zawiera ona jedno dodatkowe pole typu string. Nie jest tu zdefiniowana funkcja "zapisz", poniewa metoda zdefiniowana w klasie bazowej jest wystarczajca i to ona jest wywoywana.

2.1.4 Delta
Klasa pochodna klasy koder_dekoder. Zawiera ona jedno pole typu string, oraz 4 metody, analogiczne jak w klasie Liczba.

3. Listing kodu.
3.1.1 koder_dekoder.h
#ifndef _totezjestdluganazwa // Zapewnienie sobie, ze ten plik nagwkowy #define _totezjestdluganazwa // skompiluj tylko raz. #include <string> #include <fstream> using namespace std; class koder_dekoder //Pocztek definicji klasy. { public: //Cz publiczna z funkcjami czysto wirtualnymi. virtual void koduj()=0; virtual void dekoduj()=0; virtual void zapisz(CString sciezka)=0; protected: std::fstream F_PlikWy; //Obiekt fstream uzywany przy zapisie. }; #endif

3.2.1 Liczba.h
#ifndef _nazwaktorejniktniewymysli //Ponownie zapewnienie sobie #define _nazwaktorejniktniewymysli // jednokrotnej kompilacji. #include <string> #include "koder-dekoder.h" //Poinformowanie kompilatora o //uyciu pliku using namespace std; //nagwkowego koder-dekoder.h, //oraz przestrzeni nazw. class Liczba: public koder_dekoder //Definicja klasy, wraz z dziedziczeniem //z klasy koder_dekoder. { protected: //Elementy zabezpieczone. int n; string s_tekst;

public: //Elementy publiczne. Liczba(string &tekst, int kod); void koduj(); //Deklaracje funkcji. void dekoduj(); virtual void zapisz(CString sciezka); friend ostream & operator<<(ostream &wyj, Liczba const &s); //Zaprzyjazniony przeciazony operator. }; #endif

3.2.2 Liczba.cpp
#include "stdafx.h" #include "Liczba.h" //Zaczenie pliku nagwkowego z definicj klasy.

Liczba::Liczba(string &tekst, int kod): s_tekst(tekst)//Definicja //konstruktora. { n=kod; } void Liczba::koduj() //Definicja funkcji kodujcej. { int dl=s_tekst.length(); for(int i=0; i<dl; i++) { s_tekst[i]=s_tekst[i]+n; } } void Liczba::dekoduj() //Definicja funkcji dekodujcej. { int dl=s_tekst.length(); for(int i=0; i<dl; i++) { s_tekst[i]=s_tekst[i]-n; } } ostream & operator<< (ostream &wyj, Liczba const &s)//Przeciony operator //wyjcia. { return wyj<<s.s_tekst; } void Liczba::zapisz(CString sciezka)//Definicja funkcji zapisu do pliku { //z wykorzystaniem przecionego operatora. F_PlikWy.open(sciezka, std::ios::out); F_PlikWy<<(*this); F_PlikWy.close(); }

3.3.1 Sowem.h
#include "Liczba.h" //Zaczenie pliku nagwkowego z definicj klasy Liczba. #ifndef _Kolejnanazwaktorejniepotrafienawetprzepisacwiecjaskopiuje #define _Kolejnanazwaktorejniepotrafienawetprzepisacwiecjaskopiuje class Slowem: public Liczba //Definicja wraz z dziedziczeniem. { string s_kod;//zmienna zawierajca sowo szyfrujce. public: Slowem(string &tekst, CString szyfr); //konstruktor void koduj(); //deklaracja funkcji kodujcej void dekoduj(); //deklaracja funkcji dekodujcej. }; #endif

3.3.2 Sowem.cpp
#include "stdafx.h" #include "Slowem.h" using namespace std; //Zaczenie pliku nagwkowego z definicj klasy //slowem. //Uycie przestrzeni nazw standardowych.

Slowem::Slowem(string &tekst, CString szyfr): Liczba(tekst, 0)//Konstruktor { CT2CA zamiana(szyfr); //Zamiana CStringa na stringa s_kod=zamiana; //Przy uyciu klasy CT2CA n=s_kod.length(); } void Slowem::koduj() //Definicja funkcji kodujacej. { for(unsigned int i=0; i<s_tekst.length(); i++) { s_tekst[i]=s_tekst[i]+s_kod[i%n]; } } void Slowem::dekoduj() //Definicja funkcji dekodujacej { for(unsigned int i=0; i<s_tekst.length(); i++) { s_tekst[i]=s_tekst[i]-s_kod[i%n]; } }

3.4.1 Delta.h
#ifndef _kolejnawyjatkowounikalnanazwa #define _kolejnawyjatkowounikalnanazwa #include "koder-dekoder.h" class Delta : public koder_dekoder //Definicja klasy wraz z dziedziczeniem. { string s_tekst;

public: Delta(string &tekst); //Deklaracje funkcji. void koduj(); void dekoduj(); void zapisz(CString sciezka); friend ostream & operator<<(ostream &wyj, Delta const &s); }; #endif

3.4.2 Delta.cpp
#include "stdafx.h" #include "Delta.h" //Zaczenie pliku nagwkowego z definicj klasy. Delta::Delta(string &tekst): s_tekst(tekst) {}; //Konstruktor. void Delta::koduj() //Definicja metody kodujcej. { int dl=s_tekst.length(); for(int i=dl; i>0; i--) { s_tekst[i]-=s_tekst[i-1]-65; } } void Delta::dekoduj() //Definicja metody dekodujcej. { int dl=s_tekst.length(); for(int i=0; i<dl; i++) { s_tekst[i+1]+=s_tekst[i]-65; } } void Delta::zapisz(CString sciezka) //Definicja metody zapisu do pliku. { F_PlikWy.open(sciezka, std::ios::out); F_PlikWy<<(*this); F_PlikWy.close(); } ostream & operator<< (ostream &wyj, Delta const &s)//Definicja //przecionego operatora { return wyj<<s.s_tekst; }

3.5.1 ChangedNameDlg.h
#include <fstream> #include <string> #include "Slowem.h" #include "Delta.h" #pragma once class Liczba;

//Zaczenie plikw nagwkowych.

class CChangedNameDlg : public CDialog {//Definicja klasy dialogu. public:

CChangedNameDlg(CWnd* pParent = NULL); enum { IDD = IDD_CHANGED_NAME}; protected: virtual void DoDataExchange(CDataExchange* pDX); protected: HICON m_hIcon; virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); DECLARE_MESSAGE_MAP() CString CS_PlikWe; std::fstream F_Plik; //Zmienne std::string S_1, S_2; //pomocnicze. koder_dekoder *wskaznik; //Wskazniki, w celu Liczba *wskaznik_na_liczbe; //wykorzystania Slowem *wskaznik_na_slowem; //polimorifzmu. Delta *wskaznik_na_delte; int i_Zadanie; //Kolejne zmienne pomocnicze CString CS_PlikWy; int i_czykoduj; CString CS_Szyfr; int i_kod; public: afx_msg void OnBnClickedButton1(); //Funkcje afx_msg void OnBnClickedButton2(); //obsugi afx_msg void OnBnClickedOk(); //przyciskw. afx_msg void OnBnClickedRadio1(); afx_msg void OnBnClickedRadio2(); afx_msg void OnBnClickedRadio3(); };

3.5.2 ChangedNameDlg.cpp
#include "stdafx.h" #include "ChangedName.h" #include "ChangedNameDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #endif CChangedNameDlg::CChangedNameDlg(CWnd* pParent /*=NULL*/) : CDialog(CChangedNameDlg::IDD, pParent) , CS_PlikWe(_T("")) //Inicjalizacja zmiennych. , i_Zadanie(0) , CS_PlikWy(_T("")) , i_czykoduj(0) , CS_Szyfr(_T("Szyfr")) , i_kod(1) { m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CChangedNameDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX);

DDX_Text(pDX, PlikWe, CS_PlikWe); DDX_Radio(pDX, IDC_RADIO1, i_Zadanie); DDV_MinMaxInt(pDX, i_Zadanie, 0, 3); DDX_Text(pDX, PlikWy, CS_PlikWy); DDX_Radio(pDX, IDC_RADIO4, i_czykoduj); DDX_Text(pDX, IDC_EDIT2, CS_Szyfr); DDX_Text(pDX, IDC_EDIT1, i_kod); DDV_MinMaxInt(pDX, i_kod, 1, 30); }

//Poczenia midzy //zmiennymi //i kontrolkami.

BEGIN_MESSAGE_MAP(CChangedNameDlg, CDialog) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, &CChangedNameDlg::OnBnClickedButton1) ON_BN_CLICKED(IDC_BUTTON2, &CChangedNameDlg::OnBnClickedButton2) ON_BN_CLICKED(IDOK, &CChangedNameDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_RADIO1, &CChangedNameDlg::OnBnClickedRadio1) ON_BN_CLICKED(IDC_RADIO2, &CChangedNameDlg::OnBnClickedRadio2) ON_BN_CLICKED(IDC_RADIO3, &CChangedNameDlg::OnBnClickedRadio3) END_MESSAGE_MAP() BOOL CChangedNameDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); SetIcon(m_hIcon, FALSE); CS_PlikWe=_T("Wybierz plik"); //Wasna CS_PlikWy=_T("Wybierz plik"); //inicjalizacja. wskaznik=0; wskaznik_na_delte=0; //Zerowanie wskaznikow wskaznik_na_liczbe=0; //Dla bezpieczenstwa. wskaznik_na_slowem=0; reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT2))->EnableWindow(0); //Dezaktywacja moliwoci edycji okna. UpdateData(0); //Przesanie danych ze zmiennych do kontrolek. return TRUE; } void CChangedNameDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0); int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CChangedNameDlg::OnQueryDragIcon() { return static_cast<HCURSOR>(m_hIcon);

10

} void CChangedNameDlg::OnBnClickedButton1() { CFileDialog we(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, _T("Pliki txt(*.txt)|*.txt||"),this); we.DoModal(); //Otwarcie okna dialogowego plikw z moliwoci //wyboru tylko plikw tekstowych. reinterpret_cast<CEdit*>(GetDlgItem(PlikWe))>SetWindowText(we.GetPathName()); //Wywietlanie w kontrolce cieki //wybranego pliku. F_Plik.open(we.GetPathName(), std::ios::in); //Otwieranie pliku. if(F_Plik.good()) //Jeli udao si otworzy plik... { F_Plik.seekp(0, std::ios::beg); //Przejcie na pocztek //pliku (dla bezpieczestwa) while(!(F_Plik.eof())) { //Wczytywanie z pliku. F_Plik>>S_2; S_1.append(S_2); S_1.append(" "); }; } F_Plik.close(); //zamkniecie pliku } void CChangedNameDlg::OnBnClickedButton2() { CFileDialog wy(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, _T("Pliki txt(*.txt)|*.txt||"),this); wy.DoModal(); //Analogicznie jak z funkcj obsugi przycisku 1. reinterpret_cast<CEdit*>(GetDlgItem(PlikWy))>SetWindowText(wy.GetPathName()); CS_PlikWy=wy.GetPathName(); //Zapamitanie cieki zapisu. } void CChangedNameDlg::OnBnClickedOk() { UpdateData(1); //Przesanie danych z kontrolek do zmiennych. switch(i_Zadanie) { //zaleznie od wartosci zmiennej stwrz dany obiekt //a nastpnie wska na niego wskanikiem "uniwersalnym" case 0: { wskaznik_na_liczbe=new Liczba(S_1, i_kod); wskaznik=wskaznik_na_liczbe; break; } case 1: { wskaznik_na_slowem= new Slowem(S_1, CS_Szyfr); wskaznik=wskaznik_na_slowem; break; } case 2: { wskaznik_na_delte=new Delta(S_1); wskaznik=wskaznik_na_delte; break; } }; //Zalenie od dania uytkownika koduj bd dekoduj.

11

if(i_czykoduj==0) wskaznik->koduj(); else wskaznik->dekoduj(); if(CS_PlikWy.Compare(_T("Wybierz plik")))wskaznik>zapisz(CS_PlikWy); //zapis do pliku, jesli wskazano ciek. delete wskaznik; //Usunicie obiektu dynamicznego. OnOK(); } void CChangedNameDlg::OnBnClickedRadio1() {//Funkcja obslugi kontrolek z pierwszego zestawu //dezaktywuje ona odpowiednie edit boxy. reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT2))->EnableWindow(0); reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT1))->EnableWindow(1); } void CChangedNameDlg::OnBnClickedRadio2() { reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT2))->EnableWindow(1); reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT1))->EnableWindow(0); } void CChangedNameDlg::OnBnClickedRadio3() { reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT2))->EnableWindow(0); reinterpret_cast<CEdit*>(GetDlgItem(IDC_EDIT1))->EnableWindow(0); }

3.6 UWAGA!
wiadomie nie umieszczam tu czci kodu, ze wzgldu na to, e nie zostaa ona przeze mnie w najmniejszym stopniu edytowana, a wic nie warto upamitnia j na papierze.

4. Algorytmy.
4.1 Kodowanie liczb.
void Liczba::koduj() //Definicja funkcji kodujcej. { int dl=s_tekst.length(); for(int i=0; i<dl; i++) { s_tekst[i]=s_tekst[i]+n; } }

Jak wida, funkcja ta po prostu zwiksza kolejno kady znak o warto "n" (ktra podawana jest przez uytkownika). Dekodowanie dziaa analogicznie, tylko zamiast dodawania, odejmuje si n, wic nie bd si w nie wgbia.

4.2 Kodowanie sowem.


void Slowem::koduj() //Definicja funkcji kodujacej. { for(unsigned int i=0; i<s_tekst.length(); i++) { s_tekst[i]=s_tekst[i]+s_kod[i%n]; }

12

Funkcja analogiczna do kodowania liczb, z tym, e zamiast liczb wykorzystuje litery (a dokadniej ich liczbowe odwzorowanie). Reszta z dzielenia (i%n) zapewnia, e kodowanie bdzie nastpowao wedug odpowiedniego znaku sowa. Dekodowanie take jest analogiczne.

4.3 Kodowanie Delta.


void Delta::koduj() //Definicja metody kodujcej. { int dl=s_tekst.length(); for(int i=dl; i>0; i--) { s_tekst[i]-=s_tekst[i-1]-65; } } void Delta::dekoduj() //Definicja metody dekodujcej. { int dl=s_tekst.length(); for(int i=0; i<dl; i++) { s_tekst[i+1]+=s_tekst[i]-65; } }

Kodowanie delta zaczynamy dla odmiany od konca ciagu znakow. Od ostatniego znaku odejmujemy wartosci liczbowa znaku przedostatniego zmniejszon o 65 (odwzorowanie litery A w kodzie ASCII, co pozwala utrzyma si w zakresie). Powtarzamy t czynno a do drugiego znaku. Znak pierwszy pozostaje bez zmian. Jest on naszym "kluczem", potrzebnym do odnalezienia znaku drugiego. Odkodowany znak drugi pozwala nam na odkodowanie znaku 3 itp... Tak te wyglda dekodowanie. Do znaku drugiego dodajemy warto pierwszego zmniejszon o 65. Powtarzamy analogicznie a do ostatniego znaku.

5.Uwagi i wnioski.
W trakcie wykonywania tego programu, stwierdziem, e biblioteki MFC nie s a tak irytujce, jakby si mogo wydawa. Wystarczy si do nich przyzwyczai (aczkolwiek kompilowania wszystkiego dwa razy ze wzgldu na notoryczne bdy linkera jako nie mog wybaczy). Wykonujc ten projekt zaczem te docenia przydatno wskanikw. Wyjtkowo pomagaj unika masowego uywania instrukcji warunkowych. Chciabym take zwrci uwag na to, i zdaj sobie spraw, e przeciyem tylko jeden operator, ale przyznam, e nie widziaem sensu w ujciu tego projektu przeciania te innych. Rwnie dobrze mogoby go nie by, ale staraem si go wcisn na si, eby "popisa si", e umiem. Mam nadziej, e zawarem wszystkie wymagane aspekty programowania obiektowego. Przepraszam za wygupy z ikon programu oraz opisem procesu.

13

You might also like