Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Выбор, размещение и задание свойств компонентов.




 Коды классов, функций и обработчиков событий

1.Интерфейс проектируемого приложения должен удовлетворять требованиям:

· интерфейс должен быть удобен и прост в использовании;

· интерфейс должен соответствовать принципу универсальности, который подразумевает поддержание основных правил построения интерфейса, характерных для основных диалоговых систем; при этом предполагается единообразие управления, единообразие назначения элементов;

· интерфейс по возможности должен обнспечивать минимальное число физических манипуляций пользователя (предполагается исключение лишних переходов).

2.Сохраните модуль главной формы под именем LR_4, а проект – под именем PR_LR_4. Главная форма приложения представлена на рис.4.4. В свойствоCaptionглавной формы занесено ШИФРОВАНИЕ / ДЕШИФРОВАНИЕ   ДЛЯ ВВОДА ДОПУСТИМЫ ПРОПИСНЫЕ РУССКИЕ БУКВЫ И СИМВОЛ-РАЗДЕЛИТЕЛЬ ‘_’. Главное меню содержит раздел Файл (с подразделами  Открыть исходный текст, Открыть шифрованный текст, Выход), раздел Операции (с подразделами Инициализация, Очистка полей) и раздел Справка (с подразделом О программе). Для подраздела Очистка полей свойство Enabled имеет значение false.

Рис.4.4 – главная форма по окончании проектирования

 

3.Наиболее часто употребляемые команды главного меню (Выход, Инициализация, Очистка полей) продублированы на инструментальной панели, расположенной под главным меню. Здесь используется простейшая по проектированию инструментальная панель. Она состоит из простой панелиPanel1 (страница Стандарт) с зачищенным свойством Caption, на которой размещены три кнопки SpeedButton1,2,3(страница Дополнительно). Двум из них даны осмысленные имена: sbtnInit (SpeedButton2), sbtnClear (SpeedButton3) (см. заголовочный файл модуля главной формы LR_4.h). Пиктограммы (изображения) помещены на кнопки через свойство Glyph соответственно из файлов dooropen, check, clear в папке …Program Files\Common Files\Borland Shared\Images\Buttons. В свойство Hint кнопок занесены соответственно всплывающие подсказки выход, инициализация, очистка полей, в свойство ShowHinttrue. Для кнопки SpeedButton3(очистка полей) свойство HelpType поставлено в значение htKeyword(режим полной подсказки).

4.Перенесите на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1, а со страницы Стандарт - компонент PopupMenu1. Двойным щелчком на компонентеPopupMenu1 перейдите в Конструктор Меню (окно Form1->PopupMenu1) и внесите разделы Сохранить и Сохранить как.

5.Остальная часть главной формы делится на три примерно равные части компонентами - панелями GroupBox1,2,3(страница Стандарт). В свойство Captionпанелейвнесено соответственно: Треугольник Паскаля, Метод Гронсфельда, По матрице.

6.На панели GroupBox1размещены две метки Label1,2(Исходный текст, Зашифрованный текст), два компонента Memo1,2 и две кнопки Button1,2(страница Стандарт) с надписями (Шифрование, Дешифрование). Заданные средой имена (значение свойства Name) Memo1, Memo2 заменены на осмысленные имена: TextPascal, CodedTextPascal (см. LR_4.h). В свойство PopupMenuкомпонента Memo1занесено значение PopupMenu1, что позволит через Memo1 задавать идентичный исходный текст для всех трех способов шифрования. Заданные средой имена (значение свойства Name) Button1, Button2 заменены на осмысленные – btnEncryptP, btnDecryptP, а свойству Enabled присвоено значение false.

7.На панели GroupBox2размещены три метки Label3,4,5(Ключ (3-8 цифр), Исходный текст, Зашифрованный текст), три компонента Memo3,4,5 (заданные средой имена заменены  на edtKeyG, TextG, CodedTextG) и две кнопки Button3,4 (заданные средой имена заменены на btnEncryptG, btnDecryptG, свойство Enabled - false).

8.На панели GroupBox3размещены три метки Label6,7,8(Ключ (буквы), Исходный текст, Зашифрованный текст), три компонента Memo6,7,8 (заданные средой имена заменены  на edtKeyM, TextM, CodedTextM) и две кнопки Button5,6 (заданные средой имена заменены на btnEncryptM, btnDecryptM, свойство Enabled - false).

 

Рис.4.5 – форма «О программе»

Рис.4.6 – главная форма с результатами тестирования

 

Рис.4.7 – окно Редактора Кода с окном Исследователя Классов

(начало структуры проекта)

Рис.4.8 – окно Редактора Кода с окном Исследователя Классов

(продолжение структуры проекта)

 

Рис.4.9 – окно Редактора Кода с окном Исследователя Классов

(окончание структуры проекта)

 

9.Перейдем к изучению кода приложения. В проекте использован модуль, не связанный с какой-либо формой. Чтобы создать такой модуль, нужно выполнить команду Файл/Новый/Другое… и открывшемся окне Новые элементы на странице Новый щелкнуть на пиктограмме Модуль. Модулю дано имя main. В заголовочном файле этого модуля main.hразмещено объявление класса, а в файле реализации модуля main.cpp – реализация класса (определения функций-элементов класса).

10.Для работы с проектом большие удобства пользователю предоставляет Исследователь Классов. По умолчанию окно Исследователя Классов (рис.4.7,8,9) появляется автоматически встроенным в окно Редактора Кода. (Оно закрывается щелчком на крестике и открывается командой Вид|ClassExplorer.) В окне Исследователя Классов можно видеть структуру своего проекта, модулей и классов. Если в окне Исследователя Классов сделать двойной щелчок на имени класса, функции или переменной, то курсор в окне Редактора Кода перейдет на строку, в которой этот класс, функция или переменная объявлена. Такая возможность относится ко всем файлам проекта, в том числе и к файлам модулей, которые не связаны с какой-либо формой. Например, на рис.4.7 представлен случай, когда двойным щелчком на имени Codec файл main.h был загружен в окно Редактора Кода.

11.Заголовочный файл main.hмодуля main

//---------------------------------------------------------------------------

 

#ifndef mainH

#define mainH

//---------------------------------------------------------------------------

//класс шифрования/дешифрования текста

class Codec

{

char* text; //исходный текст

char* codedtext; //зашифрованный текст

int** Ptriangle; // треугольник Паскаля

int keyG[9]; //ключ для шифра Гронсфельда, в нулевом байте –

// длина ключа

char* keyM; //ключ для шифра по матрице

 public:

Codec();                 //конструктор

~Codec();                //деструктор

void SetText(char* text); //задать исходный текст

char* GetText();         //получить исходный текст

void SetCodedText(char* text);//задать шифрованный текст

char* GetCodedText();    //получить шифрованный текст

void SetKeyG(char* strkey); //задать ключ для метода Гронсфельда

  void SetKeyM(char* strkey); //задать ключ для шифрования по матрице

int TextLen();           //получить длину исходного текста

int CodedTextLen();      //получить длину шифрованного текста

void EncryptP();         //шифровать по треугольнику Паскаля

void EncryptM();         //шифровать по матрице

void EncryptG();         //шифровать методом Гронсфельда

void DecryptP();         //дешифровать по треугольнику Паскаля

void DecryptM();         //дешифровать по матрице

void DecryptG();         //дешифровать методом Гронсфельда

 } *A;                            //указатель на объект класса

#endif

 

12.Файл реализации main.cppмодуля main

 

//---------------------------------------------------------------------------

 

 

#pragma hdrstop

 

#include "main.h"

#include<string.h>

 

//---------------------------------------------------------------------------

 

#pragma package(smart_init)

//Примем, что в исходном тексте не встретится слов, содержащих более //30 букв. Будем строить треугольник Паскаля для такого количества //строк

const int N = 30;

//Конструктор. Строится треугольник Паскаля и инициализируются //остальные данные-элементы класса

Codec::Codec()

{

//выделяем память под треугольник

Ptriangle = new int*[N];

for(int i = 0; i < N; i++) Ptriangle[i] = new int[i+1];

//заполняем треугольник числами

Ptriangle[0][0] = 1;

Ptriangle[1][0] = 1;

Ptriangle[1][1] = 1;

for(int i = 2; i < N; i++)

{

   Ptriangle[i][0] = 1;

   Ptriangle[i][i] = 1;

   for(int j=1; j<i; j++)

      Ptriangle[i][j] = Ptriangle[i-1][j-1] + Ptriangle[i-1][j];

}

//выделяем память под тексты и ключ

text = new char[1];

codedtext = new char[1];

keyM = new char[1];

}

 

//Деструктор

Codec::~Codec()

{

//чистим память от исходного текста

delete [] text;

//от зашифрованного текста

delete [] codedtext;

//от ключа для шифрования по матрице

delete [] keyM;

 

//чистим память от треугольника

for(int i = 0; i < N; i++) delete [] Ptriangle[i];

delete [] Ptriangle;

}

 

//задаем исходный текст

void Codec::SetText(char* text)

{

delete [] this->text;

this->text = new char[strlen(text) + 1];//плюс один для нулевого байта

strcpy(this->text,text);

}

 

//получаем исходный текст

char* Codec::GetText()

{return text;}

 

//задаем шифрованный текст

void Codec::SetCodedText(char* text)

{

this->codedtext = new char[strlen(text) + 1];

strcpy(this->codedtext,text);

}

 

//получаем зашифрованный текст

char* Codec::GetCodedText()

{return codedtext;}

 

//задаем ключ для шифра Гронсфельда

void Codec::SetKeyG(char* strkey)

{

keyG[0] = strlen(strkey);

for(int i = 0; i < keyG[0]; i++)

      keyG[i+1] = strkey[i] - '0';

}

 

//задаем ключ для шифра по матрице

void Codec::SetKeyM(char* strkey)

{

delete [] keyM;

keyM = new char[strlen(strkey) + 1];

strcpy(keyM,strkey);

}

 

//получаем длину исходного текста

int Codec::TextLen()

{return strlen(text);}

 

//получаем длину зашифрованного текста

int Codec::CodedTextLen()

{return strlen(codedtext);}

 

//шифруем по треугольнику Паскаля

void Codec::EncryptP()

{

delete [] codedtext;

codedtext = new char[strlen(text) + 1];

char word[N + 1] = {'\0'},//слово

   *t,         //указатель на текущую букву в исходном тексте

   *ct;  //указатель на текущую букву в зашифрованном тексте

bool flag = true;//признак достижения конца текста

t = text;

ct = codedtext;

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

    if(word[i] == '_')

    {

       word[i] = '\0'; break;

    }

    i++;

}

//шифруем слово по треугольнику Паскаля

for(int j = 0; j < i; j++)

{

    //на сколько будет отстоять зашифрованная буква

    int n = Ptriangle[i - 1][j] % 32;

    //получаем зашифрованную букву

    *ct = word[j] + n;

    //если вышли за пределы алфавита, то сдвиг по кругу

    if(*ct > 'Я') *ct -= 32;

    //сдвигаем указатель на следующую букву

    ct++;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифруем текст, зашифрованный по треугольнику Паскаля

void Codec::DecryptP()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

   *t,        //указатель на текущую букву в исходном тексте

   *ct;  //указатель на текущую букву в зашифрованном тексте

bool flag = true;//признак достижения конца текста

t = text;

ct = codedtext;

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

    if(word[i] == '_')

    {

       word[i] = '\0'; break;

    }

    i++;

}

//дешифруем слово

for(int j = 0; j < i; j++)

{

    int n = Ptriangle[i-1][j] % 32;

    *t = word[j] - n;

    if(*t < 'А') *t += 32;

    t++;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

//шифрование методом Гронсфельда

void Codec::EncryptG()

{

delete [] codedtext;

codedtext = new char[strlen(text)];

char word[N + 1] = {'\0'},//слово

   *t = text,      //указатель на текущую букву в исходном тексте

   *ct = codedtext;//указатель на текущую букву в зашифрованном

                            //тексте

bool flag = true; //признак достижения конца текста

int k = 1;

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

    if(word[i] == '_')

    {

          word[i] = '\0'; break;

    }

    i++;

}

 

//шифруем слово

for(int j = 0; j < i; j++)

{

    //получаем зашифрованную букву

    *ct = word[j] + keyG[k++];

    //чтобы не выйти за пределы алфавита

     if(*ct > 'Я') *ct -= 32;

    //сдвигаем указатель на следующую букву

    ct++;

    //используем ключ циклически

    if(k > keyG[0]) k = 1;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифрование методом Гронсфельда

void Codec::DecryptG()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

   *t = text,      //указатель на текущую букву в исходном тексте

   *ct = codedtext;//указатель на текущую букву в зашифрованном

                            //тексте

bool flag = true;  //признак достижения конца текста

int k = 1;

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

    if(word[i] == '_')

    {

       word[i] = '\0'; break;

    }

    i++;

}

 

//дешифруем слово

for(int j = 0; j < i; j++)

{

    *t = word[j] - keyG[k++];

    if(*t < 'А') *t += 32;

    t++;

    if(k > keyG[0]) k = 1;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

//шифрование по матрице

void Codec::EncryptM()

{

delete [] codedtext;

codedtext = new char[strlen(text) + 1];

char word[N + 1] = {'\0'},//слово

   *t = text,        //указатель на текущую букву в исходном тексте

   *ct = codedtext;//указатель на текущую букву в зашифрованном

                            //тексте

bool flag = true;  //признак достижения конца текста

int k = 0;

int keylen = strlen(keyM);

 

//пока не достигли конца текста

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *t++)

{

    if(word[i] == '_')

    {

       word[i] = '\0'; break;

    }

    i++;

}

 

//шифруем слово

for(int j = 0; j < i; j++)

{

    //вычитаем два раза А, чтобы получить именно номер буквы,

    //затем к остатку от деления на количество букв прибавляем А,

    //чтобы получить ASCII код буквы

    *ct++ = (word[j] + keyM[k++] - 'А' - 'А') % 32 + 'А';

    if(k == keylen) k = 0;

}

//после слова добавляем символ-разделитель

*ct++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец зашифрованного текста

*--ct = '\0';

}

 

//дешифрование по матрице

void Codec::DecryptM()

{

delete [] text;

text = new char[strlen(codedtext) + 1];

char word[N + 1] = {'\0'},//слово

   *t = text,        //указатель на текущую букву в исходном тексте

   *ct = codedtext;//указатель на текущую букву в зашифрованном

                            //тексте

bool flag = true; //признак достижения конца текста

int k = 0;

int keylen = strlen(keyM);

 

while(flag)

{

int i = 0;

//берем очередное слово

while(flag = word[i] = *ct++)

{

    if(word[i] == '_')

    {

       word[i] = '\0'; break;

    }

    i++;

}

 

//дешифруем слово

for(int j = 0; j < i; j++)

{

    *t++ = (word[j] - keyM[k++] + 32) % 32 + 'А';

    if(k == keylen) k = 0;

}

//после слова добавляем символ-разделитель

*t++ = '_';

}

//строка должна заканчиваться нулевым байтом, поэтому

//добавляем его в конец дешифрованного текста

*--t = '\0';

}

 

13.Заголовочный файл LR_4.h модуля LR_4 главной формы Form1

 

//---------------------------------------------------------------------------

 

#ifndef LR_4H

#define LR_4H

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <Menus.hpp>

#include <Buttons.hpp>

#include <ExtCtrls.hpp>

#include <Dialogs.hpp>

//---------------------------------------------------------------------------

class TForm1 : public TForm

{

__published:   // IDE-managed Components

   TGroupBox *GroupBox1;

   TGroupBox *GroupBox2;

   TGroupBox *GroupBox3;

   TLabel *Label1;

   TMemo *TextPascal;

   TLabel *Label2;

   TMemo *CodedTextPascal;

   TButton *btnEncryptP;

   TButton *btnDecryptP;

   TLabel *Label3;

   TMemo *edtKeyG;

   TLabel *Label4;

   TMemo *TextG;

   TLabel *Label5;

   TMemo *CodedTextG;

   TButton *btnEncryptG;

   TButton *btnDecryptG;

   TLabel *Label6;

   TMemo *edtKeyM;

   TLabel *Label7;

   TMemo *TextM;

   TLabel *Label8;

   TMemo *CodedTextM;

   TButton *btnEncryptM;

   TButton *btnDecryptM;

   TMainMenu *MainMenu1;

   TMenuItem *N1;

   TMenuItem *N2;

   TMenuItem *N3;

   TMenuItem *N4;

   TMenuItem *N5;

   TMenuItem *N6;

   TMenuItem *N7;

   TMenuItem *N8;

   TMenuItem *N9;

   TPanel *Panel1;

   TSpeedButton *sbtnInit;

   TSpeedButton *sbtnClear;

   TSpeedButton *SpeedButton1;

   TOpenDialog *OpenDialog1;

   TSaveDialog *SaveDialog1;

   TPopupMenu *PopupMenu1;

   TMenuItem *N10;

   TMenuItem *N11;

   void __fastcall SpeedButton1Click(TObject *Sender);

   void __fastcall N6Click(TObject *Sender);

   void __fastcall N9Click(TObject *Sender);

   void __fastcall sbtnInitClick(TObject *Sender);

   void __fastcall N7Click(TObject *Sender);

   void __fastcall sbtnClearClick(TObject *Sender);

   void __fastcall N8Click(TObject *Sender);

   void __fastcall N4Click(TObject *Sender);

   void __fastcall N5Click(TObject *Sender);

   void __fastcall btnEncryptPClick(TObject *Sender);

   void __fastcall btnDecryptPClick(TObject *Sender);

   void __fastcall btnEncryptGClick(TObject *Sender);

   void __fastcall btnDecryptGClick(TObject *Sender);

   void __fastcall btnEncryptMClick(TObject *Sender);

   void __fastcall btnDecryptMClick(TObject *Sender);

   void __fastcall FormClose(TObject *Sender, TCloseAction &Action);

   void __fastcall N10Click(TObject *Sender);

   void __fastcall N11Click(TObject *Sender);

private:  // User declarations

public:            // User declarations

   __fastcall TForm1(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm1 *Form1;

//---------------------------------------------------------------------------

#endif

 

14.Файл реализации LR_4.cpp модуля LR_4 главной формы Form1

 

//---------------------------------------------------------------------------

 

#include <vcl.h>

#pragma hdrstop

 

#include "LR_4.h"

#include "main.h"

#include <stdio.h>

#include "about.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

   : TForm(Owner)

{

//очистка полей

TextPascal->Text = "";

CodedTextPascal->Text = "";

edtKeyG->Text = "";

TextG->Text = "";

CodedTextG->Text = "";

edtKeyM->Text = "";

TextM->Text = "";

CodedTextM->Text = "";

}

//---------------------------------------------------------------------------

//способы шифрования

//1 - по треугольнику Паскаля

//2 - методом Гронсфельда

//3 - по матрице

int methods[3] = {1,2,3};

//---------------------------------------------------------------------------

void __fastcall TForm1::SpeedButton1Click(TObject *Sender)

{

Close();       

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::N6Click(TObject *Sender)

{

 exit(0);      

}

//---------------------------------------------------------------------------

//инициализация

 

void __fastcall TForm1::sbtnInitClick(TObject *Sender)

{

//создание экземпляра класса

A = new Codec();

//активирование кнопок

btnEncryptP->Enabled = true;

btnDecryptP->Enabled = true;

btnEncryptG->Enabled = true;

btnDecryptG->Enabled = true;

btnEncryptM->Enabled = true;

btnDecryptM->Enabled = true;

//деактивация инициализации и активация очистки

sbtnInit->Enabled = false;

sbtnClear->Enabled = true;

N7->Enabled = false;

N8->Enabled = true;

 

}

//---------------------------------------------------------------------------

//инициализация

void __fastcall TForm1::N7Click(TObject *Sender)

{

 sbtnInitClick(Sender);

}

//---------------------------------------------------------------------------

//очистка полей формы и освобождение памяти из-под объекта класса

void __fastcall TForm1::sbtnClearClick(TObject *Sender)

{

//удаление экземпляра класса

delete A;

//деактивация кнопок

btnEncryptP->Enabled = false;

btnDecryptP->Enabled = false;

btnEncryptG->Enabled = false;

btnDecryptG->Enabled = false;

btnEncryptM->Enabled = false;

btnDecryptM->Enabled = false;

//очистка полей

TextPascal->Text = "";

CodedTextPascal->Text = "";

edtKeyG->Text = "";

TextG->Text = "";

CodedTextG->Text = "";

edtKeyM->Text = "";

TextM->Text = "";

CodedTextM->Text = "";

//активация инициализации и деактивация очистки

sbtnInit->Enabled = true;

sbtnClear->Enabled = false;

N7->Enabled = true;

N8->Enabled = false;

}

//---------------------------------------------------------------------------

//очистка

void __fastcall TForm1::N8Click(TObject *Sender)

{

 sbtnClearClick(Sender);

}

//---------------------------------------------------------------------------

//открытие файла с исходным текстом

void __fastcall TForm1::N4Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

FILE *fp = fopen(OpenDialog1->FileName.c_str(), "r");

//определяем размер текста

fseek(fp, 0, SEEK_END);

int textlen = ftell(fp);

fseek(fp, 0, SEEK_SET);

 

char* str = new char[textlen + 1];

fgets(str, textlen + 1, fp);

fclose(fp);

TextPascal->Text = str;

TextG->Text = str;

TextM->Text = str;

delete [] str;

}

}

//---------------------------------------------------------------------------

//открытие файла с зашифрованным текстом

void __fastcall TForm1::N5Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

FILE *fp = fopen(OpenDialog1->FileName.c_str(), "rb");

 

//считывание из файла количества символов в тексте

int textlen;

fread(&textlen, sizeof(int), 1, fp);

 

//инфа о методе, которым зашифрован текст

int method;

fread(&method, sizeof(int), 1, fp);

 

//считываем сам зашифрованный текст

char *str = new char[textlen + 1];

fread(str, sizeof(char), textlen, fp);

str[textlen] = '\0';

 

fclose(fp);

 

switch(method)

{

case 1: CodedTextPascal->Text = str; break;

case 2: CodedTextG->Text = str; break;

case 3: CodedTextM->Text = str; break;

}

delete [] str;

}

}

//---------------------------------------------------------------------------

//шифрование текста по треугольнику Паскаля

void __fastcall TForm1::btnEncryptPClick(TObject *Sender)

{

A->SetText(TextPascal->Text.c_str());

A->EncryptP();

CodedTextPascal->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen = A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[0], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование текста, зашифрованного по треугольнику Паскаля

void __fastcall TForm1::btnDecryptPClick(TObject *Sender)

{

A->SetCodedText(CodedTextPascal->Text.c_str());

A->DecryptP();

TextPascal->Text = A->GetText();

}

//---------------------------------------------------------------------------

//шифрование текста методом Гронсфельда

void __fastcall TForm1::btnEncryptGClick(TObject *Sender)

{

if(edtKeyG->Text.Length() < 3)

{

   MessageBox(NULL, "Длина ключа мала!", "Ошибка", 0);

   return;

 }

else if(edtKeyG->Text.Length() > 8)

{

    MessageBox(NULL, "Длина ключа велика!", "Ошибка", 0);

    return;

}

A->SetKeyG(edtKeyG->Text.c_str());

A->SetText(TextG->Text.c_str());

A->EncryptG();

CodedTextG->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen=A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[1], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование текста методом Гронсфельда

void __fastcall TForm1::btnDecryptGClick(TObject *Sender)

{

if(edtKeyG->Text.Length() < 3)

{

   MessageBox(NULL, "Длина ключа мала!", "Ошибка", 0);

   return;

}

else if(edtKeyG->Text.Length() > 8)

{

    MessageBox(NULL, "Длина ключа велика!", "Ошибка", 0);

    return;

}

A->SetKeyG(edtKeyG->Text.c_str());

A->SetCodedText(CodedTextG->Text.c_str());

A->DecryptG();

TextG->Text = A->GetText();

}

//---------------------------------------------------------------------------

//шифрование по матрице

void __fastcall TForm1::btnEncryptMClick(TObject *Sender)

{

A->SetKeyM(edtKeyM->Text.c_str());

A->SetText(TextM->Text.c_str());

A->EncryptM();

CodedTextM->Text = A->GetCodedText();

 

//открываем диалог сохранения в файле

if(SaveDialog1->Execute())

{

FILE *fp = fopen(SaveDialog1->FileName.c_str(), "wb");

int codedtextlen = A->CodedTextLen();

//записываем в файл количество зашифрованных символов

fwrite(&codedtextlen, sizeof(int), 1, fp);

//способ шифрования

fwrite(&methods[2], sizeof(int), 1, fp);

//зашифрованный текст

fwrite(A->GetCodedText(), sizeof(char), codedtextlen, fp);

fclose(fp);

}

}

//---------------------------------------------------------------------------

//дешифрование по матрице

void __fastcall TForm1::btnDecryptMClick(TObject *Sender)

{

A->SetKeyM(edtKeyM->Text.c_str());

A->SetCodedText(CodedTextM->Text.c_str());

A->DecryptM();

TextM->Text = A->GetText();

}

//---------------------------------------------------------------------------

 

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)

{

if(sbtnClear->Enabled) delete A;

}

//---------------------------------------------------------------------------

//показ формы "О программе"

void __fastcall TForm1::N9Click(TObject *Sender)

{

//создание формы

Application->CreateForm(__classid(TForm2),&Form2);

//показ формы

Form2->ShowModal();

//освобождение ресурсов

Form2->Free();

}

//-----------------------------------------------------------------------------

//сохранить текст из окна Memo1 (TextPascal)

AnsiString MyFName = "";

void __fastcall TForm1::N10Click(TObject *Sender)

{

if(MyFName != "")

   TextPascal->Lines->SaveToFile(MyFName);

else

   if(SaveDialog1->Execute())

   {

     MyFName = SaveDialog1->FileName;

     TextPascal->Lines->SaveToFile(SaveDialog1->FileName);

   }

}

//---------------------------------------------------------------------------

//сохранить как

void __fastcall TForm1::N11Click(TObject *Sender)

{

SaveDialog1->FileName = MyFName;

if(SaveDialog1->Execute())

   {

     MyFName = SaveDialog1->FileName;

     TextPascal->Lines->SaveToFile(SaveDialog1->FileName);

   }

}

//---------------------------------------------------------------------------

 

15.На рис.4.5 представлена дополнительная форма «О программе». Это пример представления информации о программе и разработчике. Для включения в проект новой пустой формы достаточно выполнить команду Файл/Новый/Форма или нажать соответствующую быструю кнопку. Модулю дополнительной формы дано имя about. На форме размещены: компонент Image1(страница Дополнительно), три метки Label1,2,3и кнопка Button1с надписьюОК для закрытия этой формы. Картинка помещена на компонент Image1через его свойство Picture из файла cbuilder в папке …Program Files\Common Files\Borland Shared\Images\Default. Для метки Label1свойству WordWrap присвоено значение true, чтобы получить возможность переноса слов длинной надписи на новую строчку. Ниже представлены заголовочный файл about.h и файл реализации about.cpp модуля about.

16.Заголовочный файл about.h модуля about

//---------------------------------------------------------------------------

 

#ifndef aboutH

#define aboutH

//---------------------------------------------------------------------------

#include <Classes.hpp>

#include <Controls.hpp>

#include <StdCtrls.hpp>

#include <Forms.hpp>

#include <ExtCtrls.hpp>

#include <Graphics.hpp>

//---------------------------------------------------------------------------

class TForm2 : public TForm

{

__published:   // IDE-managed Components

   TLabel *Label1;

   TLabel *Label2;

   TLabel *Label3;

   TButton *Button1;

   TImage *Image1;

   void __fastcall Button1Click(TObject *Sender);

private:  // User declarations

public:            // User declarations

   __fastcall TForm2(TComponent* Owner);

};

//---------------------------------------------------------------------------

extern PACKAGE TForm2 *Form2;

//---------------------------------------------------------------------------

#endif

17.Файл реализации about.cpp модуля about

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

 

#include "about.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm2 *Form2;

//---------------------------------------------------------------------------

__fastcall TForm2::TForm2(TComponent* Owner)

   : TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm2::Button1Click(TObject *Sender)

{

Close();       

}

//---------------------------------------------------------------------------

Тестирование и использование приложения

1.Запустите приложение на выполнение, нажав быстрые кнопки Сохранить все и Запуск. Щелкните на кнопке ОК формы «О программе». На главной форме подраздел меню Очистка полей, дублирующая его кнопка инструментальной панели и кнопки Шифрование, Дешифрование окажутся недоступными.

2. В окне TextPascal (Memo1)наберите исходный текст (см. рис.4.6). Щелчком правой кнопкой мыши на окне вызовите всплывающее меню и командой сохранить или сохранить как выведите исходный текст в текстовый файл. Командой Файл/Открыть исходный текст  выведите исходный текст в остальные окна исходного текста. Команда главного меню Операции/Инициализация или щелчок на дублирующей ее кнопке инструментальной панели инициализация сделают доступными  команду Операции\Очистка полей,  кнопку инструментальной панели очистка полей и кнопки Шифрование, Дешифрование, и недоступными команду Операции/Инициализация и кнопку инициализация.

3. Зашифровать исходный текст всеми тремя способами  и сохранить зашифрованные тексты с возможностью дешифрования. Для этого нужно, щелкая на кнопках Шифрование, в диалоговом окне сохранения файла указывать имя файла и закрывать окно кнопкой Сохранить.

4. Дешифровать зашифрованные тексты. Для этого, поочередно стирая исходный текст, щелкайте на кнопках Дешифрование.

5. Вывести на экран зашифрованные тексты. Для этого, стерев зашифрованные тексты, вводите команду Файл\Открыть шифрованный текст и указывайте имена файлов. Убедитесь в правильности операций, повторив п.4. На этом тестирование приложения завершается.

6. Введите команду Операции/Очистка полей или щелкните на кнопке очистка полей. Зашифруйте и дешифруйте произвольные тексты, большие в 3-4 раза  тестируемого текста.

7. Командой Файл/Выход или щелчком на кнопке выход завершите выполнение приложения.

 

Контрольные вопросы

1.Как шифровать текст по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

2.Как шифровать слово по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

3.Как шифровать букву по треугольнику Паскаля, методом Гронсфельда, по матрице? Приведите блок-схемы алгоритмов.

4.Как выводятся в файл результаты шифрования?

5.Как дешифровать находящийся в файле зашифрованный текст?

6.Какие возможности дает использование в проекте модулей без форм? Как создать такой модуль? Что он содержит?

7.Объясните содержание класса Codec по его объявлению.

8.Как выполняется директива условной компиляции?

9.Расскажите о реализации класса Codec. С какой целью реализация класса отделяется от его объявления?

10. Как выполняется конструктор класса?

11. Как выполняется деструктор класса?

12. Укажите в коде точки, где вызывается конструктор класса.

13. Где и как нужно изменить код, чтобы вывести количество вызовов конструктора?

14. Укажите в коде точки, где вызывается деструктор класса.

15. Где и как нужно изменить код, чтобы вывести количество вызовов деструктора?

16. Как в приложении дать сведения о приложении и его разработчике? Приведите примеры.

17. Как осуществляется в проекте связь между модулями?

18. Расскажите о порядке проектирования инструментальной панели. Как связать панель с меню?

19.Какие возможности предоставляет пользователю Исследователь Классов?

20. Расскажите о возможных вариантах интерфейса для данного задания.

 



ЛАБОРАТОРНАЯ  РАБОТА  5

ПРЕОБРАЗОВАНИЕ И ВЫЧИСЛЕНИЕ АРИФМЕТИЧЕСКИХ ВЫРАЖЕНИЙ С ПОМОЩЬЮ СТЕКА

 

Введение

    Инфиксная запись (нотация) – обычная форма записи математических выражений, в которой знаки операций расположены между операндами. Вычисления производят в соответствии с приоритетом операций.

        

Обратная польская запись (постфиксная запись, польская инверсная запись, ПОЛИЗ) – форма записи математических выражений, в которой операнды расположены перед знаками операций. Операнды в выражении при письменной записи разделяются пробелами.

Например, инфиксная запись: 7-2*3, ПОЛИЗ: 7 2 3 * - .

 

Алгоритм вычисления:

· выражение читается слева направо;

· когда в выражении встречается знак операции, выполняется соответствующая операция над двумя последними встретившимися перед ним операндами в порядке из записи;

· результат операции заменяет в выражении последовательность её операндов и её знак, после чего выражение вычисляется дальше по тому же правилу;

· результатом вычисления выражения становится результат последней вычисленной операции (в примере равен 1).

        

Префикснаязапись (польская запись) – это форма записи логических, арифметических и алгебраических выражений. Здесь оператор располагается слева от операндов.

Например, инфиксная запись: (5-6)*7, префиксная запись: * - 5 6 7.

 

    Стек – (англ. Stack – стопка) – структура данных с методом доступа к элементам структуры LIFO (англ. Last InFirst Out, «последним пришел – первым вышел»).

        

Добавление элемента, называемое проталкиванием (push), возможно только в вершину стека (добавленный элемент становится первым сверху).

 

    Удаление элемента, называемое также выталкиванием (pop), возможно также только из вершины стека, при этом второй сверху элемент становится верхним.

 

Целью данной лабораторной работы является изучение программного продукта, реализующего с помощью стека алгоритмы преобразования инфиксной записи исходного арифметического выражения в постфиксную запись и префиксную запись, а также вычисление значения арифметического выражения, представленного в постфиксной записи. (В общем виде преобразуемого арифметического выражения допустимо использование строчных и прописных латинских букв и числовых целых и вещественных констант, а в преобразуемом и затем вычисляемом выражении – вещественных чисел.)

Кроме того, в данной работе будет продолжено изучение новых компонентов среды Builder. Здесь будут использованы следующие интерфейсные компоненты: ImageList – список изображений, ActionList - диспетчер действий, ToolBar – инструментальная панель.

Алгоритмы

Преобразование инфиксной записи в постфиксную запись

    Инфиксная запись (тип – строка) является исходной; при преобразовании каждый символ рассматривается поочередно.

1.Если символ или последовательность символов – число или переменная (операнд), то он помещается в выходную строку – постфиксную запись.

2.Если очередной символ – знак операции (+, -, *, /), или открывающая скобка, то приоритет данной операции сравнивают с приоритетом операции на вершине стека. Операции умножения и деления имеют приоритет, равный 2, операции сложения и вычитания имеют приоритет, равный 1, а открывающая скобка - равный 3. После получения символа проверяется стек.

а.Если стек пуст, или находящийся на его вершине символ имеет меньший приоритет, чем приоритет текущего символа, то текущий символ помещается в стек.

б.Если символ, находящийся на вершине стека, имеет приоритет, больший или равный приоритету текущего символа, то символы пересылают из стека в выходную строку до тех пор, пока выполняется это условие; затем переходят к пункту а.

3.Если текуший символ – открывающая скобка, то её помещают в стек.

4.Если текуший символ – закрывающая скобка, то символы из стека извлекают в выходную строку до тех пор, пока в стеке не появится открывающая скобка, которую отбрасывают. Закрывающая скобка также отбрасывается.

5.Если все символы входной строки просмотрены, а в стеке еще остаются знаки операций, то их из стека переносят в выходную строку.

Преобразование инфиксной записи в префиксную запись

1.Реверсируют исходную строку справа налево, сохраняя порядок скобок.

2.Преобразуют полученную строку в постфиксную запись.

3.Снова реверсируют строку справа налево и получают префиксную запись.

Вычисление выражений

    Для вычисления выражений исходную инфиксную запись сначала преобразуют в постфиксную запись, а затем действуют по следующему алгоритму.

1.Если очередные символы входной строки – число, то его помещают в стек.

2.Если очередной символ входной строки – знак операции, то из стека извлекают два верхних числа, используют их в качестве операндов для этой операции, а результат помещают в стек.

3.Когда вся входная строка будет просмотрена, в стеке остается одно число, которое и будет результатом вычисления выражения.

 

Проектирование приложения.










Последнее изменение этой страницы: 2018-05-29; просмотров: 199.

stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда...