Создание базового класса строка, строки идентификатора и десятичной строки

Курсовая работа по предмету «Программирование»
Информация о работе
  • Тема: Создание базового класса строка, строки идентификатора и десятичной строки
  • Количество скачиваний: 144
  • Тип: Курсовая работа
  • Предмет: Программирование
  • Количество страниц: 49
  • Язык работы: Русский язык
  • Дата загрузки: 2015-01-16 05:14:14
  • Размер файла: 132.61 кб
Помогла работа? Поделись ссылкой
Информация о документе

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

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования
Балтийский государственный технический университет «Военмех»
им. Д.Ф.Устинова.








КУРСОВАЯ РАБОТА
Создание базового класса строка, строки идентификатора и десятичной строки
Создание графического интерфейса

Руководитель темы ______________
дата и подпись
Исполнитель темы








Санкт-Петербург
2014
СОДЕРЖАНИЕ
Введение…………………………………………………………………...3
Техническое задание…………………………………………………….. 4
1. Класс строка…………………………………………………………....7
1.1. Базовый класс строка……………………………………………...7
1.2. Строка идентификатор…………………………………………….8
1.3. Десятичная строка………………………………………………...8
2. Интерфейс……………………………………………………………....9
2.1. Класс Desk (рабочий стол)………………………………………..9
2.2. Класс Menu (меню/подменю)……………………………………..10
2.3. Класс MenuItem (пункт меню) ……………………………………11
2.4 Класс Listbox (текстовый бокс/список) …………………………...11
2.5 Класс ListItem (элемент списка)…………………………………... 12
2.6 Описание…………………………………………………………….13
Заключение………………………………………………………………..14
Список литературы……………………………………………………….15
3.Приложения…………………………………………………………….16
3.1 Файл mystring.h…………………………………………………….16
3.2 Файл mystring.cpp………………………………………………… 17
3.3 Файл Friends.h……………………………………………………….25
3.4 Файл Friends.cpp …………………………………………………...25
3.5 Файл Desk.h……………………………………………………….. 25
3.6 Файл Desk.cpp ……………………………………………………..27
3.7 Файл menu.h ……………………………………………………….37
3.8 Файл Menu.cpp ……………………………………………………38
3.9 Файл Listbox.h …………………………………………………….43
3.10 Файл Listbox.cpp ………………………………………………...44
3.11 Файл main.cpp …………………………………………………....46
3.12 Изображения……………………………………………………...48


Введение
Целью данной работы является создание класса «строка» и производных классов от него, а также разработка интерфейса для ввода начальных значений, отображения результатов и тестирования методов собственного класса.
Для достижения поставленной цели были осуществлены следующие задачи:
1. Разработка класса рабочего стола. В него будут входить такие методы как: отрисовка рабочего стола, ввод числовых и строковых данных, вывод результатов и сообщений об ошибках, реализация команд меню и т.д. Задачей класса будет являться выполнение функций, которые к нему привязаны.
2. Разработка класса графического меню. В данный класс будут входить такие методы как: отрисовка элементов меню и подменю, реализация механизма развёртывания и свёртывания подменю, перемещения между пунктами меню и подменю, механизма выбора пункта меню и т.д.
3. Разработка классов: базовая строка, строка идентификатор, десятичная строка согласно техническому заданию.








Техническое задание
Описать базовый класс строка
Обязательные члены класса:
1) указатель на char - хранит адрес динамически выделенной памяти для размещения символов строки;
2) значение типа int - хранит длину строки в байтах.
Обязательные методы должны выполнять следующие действия:
1) конструктор без параметров;
2) конструктор, принимающий в качестве параметра Си-строку (заканчивается нулевым байтом);
3) конструктор, принимающий в качестве параметра символ (char);
4) конструктор копирования;
5) деструктор.
6) очистка строки (сделать строку пустой);
Производный от Строка класс Строка-идентификатор.
Строки данного класса строятся по правилам записи идентификаторов в СИ, и могут включать в себя только те символы, которые могут входить в состав Си-идентификаторов. Если исходные данные противоречат правилам записи идентификатора, то создается пустая СТРОКА_ИДЕНТИФИКАТОР.
Обязательные методы:
1) Конструктор без параметров;
2) Конструктор, принимающий в качестве параметра Си-строку (заканчивается нулевым байтом);
3) Конструктор копирования;
4) Деструктор.
5) Перевод всех символов строки(кроме цифр) в верхний регистр.
Переопределить следующие операции:
1) присваивание (=);
2) оператор == -проверка на равенство;
3) индексное выражение [];
Производный от Строка класс Десятичная строка.
Строки данного класса могут содержать только символы десятичных цифр и символы – и +, задающие знак числа. Символы – или + могут находиться только в первой позиции числа, причем символ + может отсутствовать, в этом случае число считается положительным. Если в составе инициализирующей строки будут встречены любые символы, отличные от допустимых, Десятичная строка принимает нулевое значение. Содержимое данных строк рассматривается как десятичное число.
Обязательные методы:
1) конструктор без параметров;
2) конструктор, принимающий в качестве параметра Си-строку
(заканчивается нулевым байтом);
3) конструктор копирования;
4) деструктор;
определяющий, можно ли представить данное число в формате char;

Переопределить следующие операции:
1) присваивание (=);
2) сложение - – арифметическая разность строк;
3) операция == – проверка на равенство;

Разработчик вправе вводить любое (с обоснованием необходимости) число дополнительных членов и методов.

Задание:
Разработать иерархию классов по следующей схеме:


с обязательной поддержкой заданных членов и методов.
Написать тестовую программу, которая:
1) динамически выделяет массив указателей на базовый класс (4-6 шт.);
2) в режиме диалога заполняет этот массив указателями на производные классы, при этом экземпляры производных классов создаются динамически с заданием начальных значений;
3) для созданных экземпляров производных классов выполняется проверка всех разработанных методов (в соответствии с вариантом задания), с выводом исходных данных и результатов на дисплей.
Режим диалога обеспечивается с помощью иерархического меню.
Основные пункты:
1. «Инициализация».
Подпункты:
1.1. "Число элементов" - задает число элементов в массиве указателей на базовый класс. Запрещается после задания числа элементов пользоваться этим пунктом меню.
1.2. "Начальное значение" - с помощью этого пункта меню можно задать номер элемента, его тип и начальное значение.

Задавать начальные значения и работать с другими пунктами меню запрещается до тех пор, пока не будет задано число элементов. Допускается задать новое начальное значение несколько раз.
2. «Тестирование»
В качестве подпунктов указываются типы строк из варианта задания и
обязательные для всех подпункты "строка" и "задание операнда", например:
2.1. «Строка»;
2.2. «Строка-идентификатор»;
2.3. «Десятичная строка»;
После выбора одного из пунктов меню предлагается выбрать один из методов списка всех обязательных методов (кроме конструкторов и деструкторов), связанных с выбранным подпунктом. Результат выводится на экран.
3. «Выход»
Значения экземпляров классов по мере их инициализации выводятся на дисплей и остаются на все время выполнения программы. После выбора операндов они подсвечиваются цветом, отличным от остальных экземпляров.



1. Класс Строка
1.1 Базовый класс Строка
Название класса: String. Является базовым классов для классов десятичная строка и строка идентификатор.
Данные-члены класса, объявленные как protected:
1) char *str - указатель на массив символов;
2) int len – переменная, хранящая длину строки.
Метода классы строка:
1) string() – конструктор без параметров, создает строку нулевой длины;
2) String(const char *) - конструктор, в качестве параметра принимающий Си-строку.;
3) String(const char) – конструктор, принимающий в качестве параметра один символ.;
4) String(const String &) – конструктор копирования;
5) ~String() – деструктор;
6) void clear(); – функция, очищающая строку;
7) char *text() – функция, возвращающая Си-строку
8) void friend report(char *) – дружественная функция выводит сообщения о работе конструкторов/деструкторов на консоль, а так же сообщения о работе конструкторов в правое диалоговое окно.

1.2 Строка идентификатор
Название класса: Identifier. Данный класс является производным классом класса String.
Методы класса Identifier:
1) Identifier() – конструктор;
2) Identifier(const char *) – конструктор, принимающий в качестве параметра си-строку.
3) Identifier(const Identifier &) – конструктор копирования;
4) ~Identifier() – деструктор;
5) Identifier operator =(const Identifier &) – переопределенная операция присваивания типа «объект»= «объект»;
6) Identifier operator =(const char *) – переопределенная операция присваивания типа «объект» = «си-строка»;
7) Identifier operator ==(const Identifier &) – переопределенная операция проверки на равенство;
8) сhar operator [](int) – переопределенная операция индекса.
1.3 Десятичная строка
Наименование класса: Tenstring. Данный класс является производным классом класса String.
Метода данного класса:
1) Tenstring () – конструктор;
2) Tenstring (const char *) – конструктор, принимающий в качестве параметра Си-строку;
3) Tenstring (const Tenstring &) – конструктор копирования;
4) ~ Tenstring () – деструктор;
5) Tenstring operator =(const Tenstring &) – переопределенная операция присваивания типа «объект» = «объект»;
6) Tenstring operator =(const char *) – переопределенная операция присваивания типа «объект» = «си-строка»;
7) Tenstring operator −( Tenstring &) – переопределенная операция разности ( арифметическая разность строк);
8) int operator ==( Tenstring &) – проверка равенства строк;
9) void ChangeChar() – проверка на представлении данного числа в char

2. Интерфейс
2.1 Класс Desk (рабочий стол).
Данные-члены класса desk объявленные как private:
1) char ClassName[3][12] – массив строк – имён тестируемых классов.
2) Menu mn, mn1, mn2, mn3, mn4, mn5 – меню и подменю – объекты класса Menu.
3) ListBox *lbx1, *lbx2 – указатели на объекты класса ListBox – правый и левый текстовые боксы.
4) INSTANCE inst[LIMIT] - массив структур INSTANCE – содержит имена и идентификаторы экземпляров тестируемых классов строк.
5) int count – количество созданных экземпляров тестируемых классов.

Методы класса desk объявленные как public:
1) Desk() - конструктор по умолчанию.
2) ~Desk() - деструктор
3) void PaintBg(void) - рисует фон рабочего стола.
4) void Go(void) - начать выполнение.
5) void Command(void) – выполнить команду меню
6) void setCount(void) - количество экземпляров тестируемых классов.
7) void Init(void) - инициализация экземпляров тестируемых классов.
8) int numInput(int,int,int,int,char *) – ввод целочисленного значения.
9) void strInput(int,int,int,int,char *,char *,int) – ввод строкового значения.
10) int str2int(char *,int &) – перевод из строки в число.
11) int dataError(int,int,int,int) – вывод сообщения об ошибке данных.
12) String *CreateInstance(int,char *) – создание экземпляра тестируемого класса
13) void numResult(int,int,int,int,char *,int) – вывод числовых данных.
14) void Msg(int,int,int,int,char *) – вывод сообщения.
15) void strclear(void) - реализация команды меню «очистка строки»
16) void sidToUpper(void) - реализация команды меню «перевод в верхний регистр»
17) void sidAssign(void) - реализация команды меню «присваивание идентификаторов»
18) void sidSub(void) - реализация команды меню «проверка на равенство идентификаторов».
19) void Ind(void) - реализация команды меню – «индексное выражение»
20) void sbtInd(void)- реализация команды меню «разность десятичных строк».
21) void sbtChangeChar(void) - реализация команды меню «представление числа в char».
22) void sbtAssign(void) - реализация команды меню «присваивание десятичных строк».
23) void sbtSub(void) - реализация команды меню «проверка на равенство десятичных строк»

2.2 Класс Menu (меню/подменю)
Данные-члены класса объявленные как private
1) Menu *supmenu – указатель на главное меню.
2) MItem mItem[10] – массив элементов (пунктов) меню.
3) int n – количество элементов меню.
4) int selected – номер выбранного элемента (пункта) меню.
5) bool visible – видимость/невидимость меню.

Методы класса:

1) Menu() – конструктор по умолчанию.
2) Menu(Menu *, int) – конструктор с параметрами.
3) ~Menu() – деструктор.
4) void Add(int,int,int,int,char *) – добавление элемента меню.
5) void setSubmenu(Menu *,int) – добавление подменю к пункту меню.
6) void Show(void) – показать меню.
7) void Hide(void) – скрыть меню.
8) void setSelect(int) – выбрать пункт меню.
9) int getSelected(void) – вернуть номер выбранного пункта меню.
10) void setEnable(int) – сделать доступным пункт меню.
11) int isEnable(int) – проверить доступность пункта меню.
12) void setDisable(int) – сделать недоступным пункт меню.
13) void Forward(void) – перейти к следующему пункту меню.
14) void Backward(void) – вернуться к предыдущему пункту меню.
15) void Upward(void) – перейти к предыдущему пункту подменю.
16) void Downward(void) – перейти к следующему пункту подменю.
17) Menu *getSubMenu(int) – получить указатель на подменю по номеру пункта меню.

2.3 Класс MenuItem (пункт меню)
Данные-члены класса объявленные как private
1) int status – статус пункта меню.
2) int x, y, w, h – положение и размеры пункта меню.
3) char text[16] – текст пункта меню.

Методы класса:
1) MenuItem() конструктор по умолчанию.
2) MenuItem(int,int,int,int, char *) – конструктор с параметрами.
3) void Show(void) – показать пункт меню.
4) void Hide(void) – скрыть пункт меню.
5) void setStatus(int) – задать статус пункта меню.
6) int getStatus(void) – получить статус пункта меню.
7) ~MenuItem() - деструктор.


2.4 Класс Listbox (текстовый бокс/список)
Данные-члены класса объявленные как private
1) int x, y, w, h – положение и размеры бокса.
2) int n – количество строк текста.
3) ListItem *lItem[STR_MAX] – массив указателей на элементы списка ( строки текста).

Методы класса:
1) ListBox(void) – конструктор по умолчанию.
2) ListBox(int,int,int,int) – конструктор с параметрами.
3) ~ListBox(void) – деструктор.
4) void Add(char *) – добавить строку текста.
5) void AddSeveral(int) – добавить несколько строк текста.
6) void UpdateRow(int,char *) – обновить строку.
7) void Clear(void) – удалить строки.
8) void Show(void) – показать бокс.
9) void Erase(void) – очистить строки.


2.5 Класс ListItem (элемент списка)
Данные-члены класса объявленные как private
1) int x, y, w, h – положение и размер элемента списка (строки текста)
2) ListBox *lbx – указатель на контейнер.

Данные-члены класса объявленные как public:
1) char text[STR_LEN+1] – строка текста.

Методы класса:
1) ListItem(void) – конструктор по умолчанию.
2) ListItem(int,int,int,int,char *) – конструктор с параметрами.
3) ~ListItem(void) – деструктор.
4) void setText(char *) – задать текст стороки.
5) void Show(void) – показать строку.
void Erase(void) – очистить строку.

2.6 Описание
Так называемый «класс окна» является структорой menu и содержит информацию об окне. Данная структура содержит большое количество компонентов, инициализирует которые - конструктор. Меню окна создается при помощи класса desk. Класс desk содержит следующие пункты:
1 Инициализация
o Число элементов
o Начальные значения
2 Тестирование
o Строка
 Очистить
o Строка-идентификатор
 Перевод в верхний регистр
 Присваивание =
 Проверка на равенство ==
 Индекс
o Десятичная строка
 Можно ли представить как char
 Присваивание =
 Вычитание −
 Проверка на равенство ==
3 Выход.
Все диалоги созданы при помощи класса listbox.


Заключение
Цель курсовой работы достигнута. Были созданы тестируемые классы: базовый класс Строка, Строка-идентификатор, Десятичная строка. Так же были реализованы классы интерфейса: класс Рабочего стола и класс Меню. Методы тестируемых классов были подключены к кнопкам меню и всплывающим окнам. Тестируемые классы и интерфейс работают корректно.
Из интерфейса был исключен пункт меню «Тестирование – Задать операнд», так как операнды вводились непосредственно при вызове конкретного метода тестируемого класса




















Список использованных источников
1 Б.И. Березин. Начальный курс С и С++. – М.:Издательство Диалог-МИФИ,
2005 г. – 248 с.
2 Р. Лафоре. Объектно-ориентированное программирование в С++. 4-е издание. – Спб.: Издательство ПИТЕР, 2004 г. – 902 с.
3 Б. Страуструп. Язык программирования С++. Специальное издание. Пер. с англ. – М.: Издательство Бином, 2011 г. – 1136 с.





















Приложение
Файл mystring.h
#ifndef MYSTRING_H
#define MYSTRING_H
#ifndef STR_MAX
#define STR_MAX 255
#endif
#include "friends.h"
class String {
protected:
char *str;
int len;

public:
String();
String(const char *);
String(const char);
String(const String &);
~String();
void clear();
char *text();
void friend report(char *);
};
class Identifier: public String {
public:
Identifier();
Identifier(const char *);
Identifier(const Identifier &);
Identifier operator ==(const Identifier &);
Identifier operator =(const char *);
Identifier operator =(const Identifier &);
char operator [](int);
~Identifier();
void toUpper();
};

class Tenstring: public String {
public:
Tenstring();
Tenstring(const char *);
Tenstring(const Tenstring &);
Tenstring operator =(const Tenstring &);
Tenstring operator =(const char *);
Tenstring operator ==(Tenstring& );
Tenstring operator -(Tenstring &);
~Tenstring();
void ChangeChar();

};

#endif /* MYSTRING_H */
Файл mystring.cpp
#include<iostream>
#include<cstring>
#include<cstdlib>
#include "mystring.h"

using namespace std;

String::String(){
report("Default String class constructor");
str = new char[STR_MAX+1];
str[0] = ;
len = 0;
}

String::String(const char *s){
report("String class constructor (const char *)");
str = new char[STR_MAX+1];
int i;
for(i=0;i<STR_MAX&&s[i]!=;i++) str[i] = s[i];
str[i] = ;
len = i-1;
}

String::String(const char ch){
report("String class constructor (const char)");
str = new char[STR_MAX+1];
str[0] = ch;
str[1] = ;
len = 1;
}

String::String(const String& ss){
report("Copy String class constructor");
str = new char[STR_MAX+1];
int i;
for(i=0;i<=ss.len;i++) str[i] = ss.str[i];
str[i] = ;
len = ss.len;
}

String::~String(){
report("String class destructor");
delete [] str;
}

char *String::text(){
return str;
}

void String::clear()
{
delete str;
len = 0;
str = new char[1];
str[0] = 0;
report("String::clear()");
}


Identifier::Identifier(){
report("Default Identifier class constructor");
}

Identifier::Identifier(const char *s){
report("Identifier class constructor (const char *)");
if(!isalpha(s[0])&&s[0]!=_) return;
int i;
for(i=1;i<STR_MAX&&s[i]!=;i++){
if(!isalnum(s[i])&&s[i]!=_) return;
}
strcpy(str,s);
len = i;
}
Identifier::Identifier(const Identifier& ss):String(ss){
report("Copy Identifier class constructor");
}

Identifier::~Identifier(){
report("Identifier class destructor");
}
Identifier Identifier::operator ==(const Identifier& ss){

report("Identifier operator ==(const Identifier &)");

// int i;
if (strcmp(str,ss.str))
report("Identifier operator != executed");
else
report("Identifier operator == executed");
return *this;}


Identifier Identifier::operator =(const Identifier& ss){
report("Identifier operator =(const Identifier &)");
if(&ss == this)
return *this;
strcpy(str,ss.str);
len = ss.len;
return *this;
}

Identifier Identifier::operator =(const char *s){
report("Identifier operator =(const char *)");
if(!isalpha(s[0])&&s[0]!=_){ str[0]=; len=0; return *this; }
int i;
for(i=0;i<STR_MAX&&s[i]!=;i++){
if(!isalnum(s[i])&&s[i]!=_){ str[0]=; len=0; return *this; }
}
strncpy(str,s,i);
str[i] = ;
len = i;
return *this;
}
char Identifier::operator [](int i)
{
report("stroka_id::operator[](int i)");
if ((i<0)||(i>=strlen(str))) {
report("index is too big(small?)");
return 0;
}
return str[i];
}

void Identifier::toUpper(){
report("Identifier member function toUpper()");
for(int i=0;str[i]!=;i++) if(islower(str[i])) str[i]=toupper(str[i]);
}

Tenstring::Tenstring(){
report("Default Tenstring class constructor");
}

Tenstring::Tenstring(const char *s){
report("Tenstring class constructor (const char *)");
int i;
if (s[0] != - && s[0] != + && (s[0] < 0 || s[0] > 9)) return;
for(i=1; i<STR_MAX && s[i] != ; i++) if (s[i] < 0 || s[i] > 9) return;
strcpy(str,s);
len = i;
}

Tenstring::Tenstring(const Tenstring& ss):String(ss){
report("Copy Tenstring class constructor");
}

Tenstring::~Tenstring(){
report("Tenstring class destructor");
}

void Tenstring::ChangeChar(){
report("Tenstring member function ChangeChar()");
if(len>4)
{report("False");
return;
}
long long int number;
number = atoll(str);
if(number > 128 || number < -127)
{
report("True");
return;
}
else
{
report("False");
return;
}


}

Tenstring Tenstring::operator =(const Tenstring& ss){
report("Tenstring operator =(const Tenstring &)");
if(&ss == this) return *this;
strcpy(str,ss.str);
len = ss.len;
return *this;
}

Tenstring Tenstring::operator =(const char *s){
report("Tenstring operator =(const char *)");
int i;
for(i=0;i<STR_MAX&&s[i]!=;i++){
if(s[i]!=0&&s[i]!=1){ str[0]=; len=0; return *this; }
}
strncpy(str,s,i);
len = i;
str[i] = ;
return *this;
}

Tenstring Tenstring::operator ==(Tenstring& ss){

if(atol(this->str)==atol(ss.str))
report("Tenstring operator == (Tenstring &)");
else
report("Tenstring operator != (Tenstring &)");
}
Tenstring Tenstring::operator -(Tenstring& ss){
report("Tenstring operator - (Tenstring &)");
int len = this->len>ss.len ? len : ss.len, res;
char res1[len];
res = atol(this->str)-atol(ss.str);
ltoa(res,res1,10);
return Tenstring(res1);
}
Файл Friends.h
#ifndef FRIENDS_H
#define FRIENDS_H

#include "listbox.h"

void report(char *);

#endif /* FRIENDS_H */

Файл Friends.cpp

#include "friends.h"
#include<iostream>

void report(char *s){
std::cout << s << std::endl;
extern ListBox *ptr;
ptr->Add(s);
}


Файл Desk.h
#ifndef DESK_H
#define DESK_H

#include "menu.h"
#include "listbox.h"
#include "mystring.h"

#define LIMIT 8

struct INSTANCE{
String *item;
int classId;
};

class Desk {

private:
char ClassName[3][12];
Menu mn, mn1, mn2, mn3, mn4, mn5;
ListBox *lbx1, *lbx2;
INSTANCE inst[LIMIT];
int count;

public:
Desk();
~Desk();
void PaintBg(void);
void Go(void);
void Command(void);
void setCount(void);
void Init(void);
int numInput(int,int,int,int,char *);
void strInput(int,int,int,int,char *,char *,int);
int str2int(char *,int &);
int dataError(int,int,int,int);
String *CreateInstance(int,char *);
void numResult(int,int,int,int,char *,int);
void Msg(int,int,int,int,char *);
void strclear(void);
void sidToUpper(void);
void sidAssign(void);
void sidSub(void);
void Ind(void);
void sbtInd(void);
void sbtChangeChar(void);
void sbtAssign(void);
void sbtSub(void);
};

#endif /* DESK_H */
Файл Desk.cpp

#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<conio.h>
#include<windows.h>
#include<graphics.h>
#include<iostream>
#include <string>
#include "desk.h"

using namespace std;

Desk::Desk(){ //конструктор
PaintBg();
mn.Add(80,30,120,30,"Инициализация");
mn.Add(260,30,120,30,"Тестирование");
mn.Add(440,30,120,30,"Выход");
mn.setDisable(1);
mn.setSelect(0);
//mn.setDisable(1);
mn1.Add(80,80,120,30,"Число элементов");
mn1.Add(80,120,120,30,"Нач-е значение");
mn1.setDisable(1);
mn1.Hide();
//Menu mn2
mn2.Add(260,80,120,30,"Строка");
mn2.Add(260,120,120,30,"Идентификатор");
mn2.Add(260,160,120,30,"Десят. строка");
mn2.Hide();
//Menu mn3
mn3.Add(390,80,120,25,"clear()");
mn3.Hide();
//Menu mn4
mn4.Add(390,120,120,25,"Toupp");
mn4.Add(390,145,120,25,"оператор =");
mn4.Add(390,170,120,25,"оператор ==");
mn4.Add(390,195,120,25,"оператор []");
// mn4.Add(390,220,120,25," vxod");
mn4.Hide();
//Menu mn5
mn5.Add(390,160,120,25,"ChangeChar()");
mn5.Add(390,185,120,25,"оператор =");
mn5.Add(390,210,120,25,"оператор ==");
mn5.Add(390,235,120,25,"оператор -");
mn5.Hide();
mn.setSubmenu(&mn1,0);
mn.setSubmenu(&mn2,1);
mn2.setSubmenu(&mn3,0);
mn2.setSubmenu(&mn4,1);
mn2.setSubmenu(&mn5,2);

lbx1 = new ListBox(20,300,292,162);
lbx2 = new ListBox(330,300,292,162);
extern void *ptr;
ptr = lbx2;

strcpy(ClassName[0],"String");
strcpy(ClassName[1],"Identifier");
strcpy(ClassName[2],"Tenstring");

for(int i=0;i<LIMIT;i++){
inst[i].item = NULL;
inst[i].classId = 0;
}
count = 0;

}

Desk::~Desk(){ //деструктор
if(lbx1) delete lbx1;
if(lbx2) delete lbx2;
}

void Desk::setCount(){ //ввод числа
int k = numInput(205,80,30,30,"count ?");
if(k>0&&k<=LIMIT){
count = k;
lbx1->AddSeveral(k);
mn1.setEnable(1);
mn1.setSelect(1);
mn1.setDisable(0);
} else dataError(205,80,5,30);
}

String *Desk::CreateInstance(int classId, char *val){ //выбор класса
switch(classId){
case 0: return new String(val);
case 1: return new Identifier(val);
case 2: return new Tenstring(val);
}
return NULL;
}

void Desk::Init(){ //запись
int k=0, classId=0, limit=39;
char val[limit+1];
char text[limit+1]; text[0]=;
k = numInput(205,120,30,30,"num ?");
if(k<=0||k>count) if(dataError(205,120,30,30)) return;
classId = numInput(205,120,30,30,"classId ?1)идентификатор2)десятичная строка");
if(classId!=0&&classId!=1&&classId!=2) if(dataError(205,120,30,30)) return;
strInput(205,120,30,30,"value ?",val,23);
k--;
lbx2->Clear();
if(inst[k].item){ delete inst[k].item;
inst[k].item = NULL;
inst[k].classId = 0;
}
inst[k].item = CreateInstance(classId,val);
inst[k].classId = classId;
strcpy(val,inst[k].item->text());
sprintf(text,"%d %s %s",k+1,ClassName[classId],val);
if(inst[k].item) lbx1->UpdateRow(++k,text);
k=0;
while(inst[k++].item);
if(k>count && !mn.isEnable(1)) mn.setEnable(1);
}

void Desk::strclear (){ //очистка строки
int len, k = numInput(520,80,25,25,"num ?");
char text[40]; text[0]=;
if(k<=0||k>count){ if(dataError(520,80,25,25)) return; }
else {

inst[k-1].item->clear();

sprintf(text,"%d %s %s",k,ClassName[0],inst[k-1].item->text());
lbx1->UpdateRow(k,text);

}

}


void Desk::sidToUpper(){ // ыерхний регистр
int k = numInput(520,120,25,25,"num ?");
if(k<=0||k>count){ if(dataError(520,120,25,25)) return; }
if(inst[k-1].classId!=1) { Msg(520,120,25,25,"Wrong data"); return; }
Identifier *pId = (Identifier*)inst[k-1].item;
pId->toUpper();
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k,ClassName[1],pId->text());
lbx1->UpdateRow(k,text);
}

void Desk::sidAssign(){//присваивание
int k,k1=0;
Identifier *pOp[2];
char op[2][6] = {"op1 ?","op2 ?"};
for(int i=0;i<2;i++){
k = numInput(520,145,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,145,25,25)) return; }
if(inst[k-1].classId!=1) { Msg(520,145,25,25,"Wrong data"); return; }
pOp[i] = (Identifier*)inst[k-1].item;
}
*pOp[0] = *pOp[1];
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k1,ClassName[1],pOp[0]->text());
lbx1->UpdateRow(k1,text);
}

void Desk::sidSub(){//сравнение
int k,k1=0;
Identifier *pOp[2];
char op[2][6] = {"op1 ?","op2 ?"};
for(int i=0;i<2;i++){
k = numInput(520,170,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,170,25,25)) return; }
if(inst[k-1].classId!=1) { Msg(520,170,25,25,"Wrong data"); return; }
pOp[i] = (Identifier*)inst[k-1].item;
}
*pOp[0] == *pOp[1];
{
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k1,ClassName[1],pOp[0]->text());
lbx1->UpdateRow(k1,text);
}}

void Desk::Ind() //индексное выражение
{
int k,k1=0;
Identifier *pOp[0];
char op[1][6] = {"op1 ?"};
for(int i=0;i<1;i++){
k = numInput(520,170,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,170,25,25)) return; }
if(inst[k-1].classId!=1) { Msg(520,170,25,25,"Wrong data"); return; }
pOp[0] = (Identifier*)inst[k-1].item;
char *id=new char[5];
strInput(520,170,25,25,"Index",id,2);
int idx;
if (!str2int(id,idx)) {

Msg(520,170,25,25,"Wrong data");
delete id;
break;
}
delete id;
char text[40],out[20]; text[0]=;
idx--;
sprintf(out,"Return value is %c",(*(Identifier*)pOp[0])[idx]);
sprintf(text,"%d %s %s",k,ClassName[2],pOp[0]->text());
lbx1->UpdateRow(k1,out);
getch();
lbx1->UpdateRow(k1,text);
}
}

void Desk::sbtInd(){//удаление
int k,k1=0;
Tenstring *pOp[3];
char op[3][6] = {"op1 ?","op2 ?","op3 ?"};
for(int i=0;i<3;i++){
k = numInput(520,210,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,210,25,25)) return; }
if(inst[k-1].classId!=2) { Msg(520,210,25,25,"Wrong data"); return; }
pOp[i] = (Tenstring*)inst[k-1].item;
}
*pOp[0] = *pOp[1] - *pOp[2];
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k1,ClassName[2],pOp[0]->text());
lbx1->UpdateRow(k1,text);
}


void Desk::sbtChangeChar(){//представить как чар
int k = numInput(520,160,25,25,"num ?");
if(k<=0||k>count){ if(dataError(520,160,25,25)) return; }
if(inst[k-1].classId!=2) { Msg(520,160,25,25,"Wrong data"); return; }
Tenstring *pId = (Tenstring*)inst[k-1].item;
pId->ChangeChar();
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k,ClassName[2],pId->text());
lbx1->UpdateRow(k,text);
}

void Desk::sbtAssign(){//присваивание
int k,k1=0;
Tenstring *pOp[2];
char op[2][6] = {"op1 ?","op2 ?"};
for(int i=0;i<2;i++){
k = numInput(520,185,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,185,25,25)) return; }
if(inst[k-1].classId!=2) { Msg(520,185,25,25,"Wrong data"); return; }
pOp[i] = (Tenstring*)inst[k-1].item;
}
*pOp[0] = *pOp[1];
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k1,ClassName[2],pOp[0]->text());
lbx1->UpdateRow(k1,text);
}

void Desk::sbtSub(){//сравнение
int k,k1=0;
Tenstring *pOp[2];
char op[2][6] = {"op1 ?","op2 ?"};
for(int i=0;i<2;i++){
k = numInput(520,210,25,25,op[i]); if(!k1) k1=k;
if(k<=0||k>count){ if(dataError(520,210,25,25)) return; }
if(inst[k-1].classId!=2) { Msg(520,210,25,25,"Wrong data"); return; }
pOp[i] = (Tenstring*)inst[k-1].item;
}
*pOp[0] == *pOp[1];
char text[40]; text[0]=;
sprintf(text,"%d %s %s",k1,ClassName[2],pOp[0]->text());
lbx1->UpdateRow(k1,text);
}


void Desk::numResult(int x,int y,int w,int h,char *s,int k){ // результат
int len = strlen(s)+5;
char *text = new char[len];
if(k<=99) sprintf(text,"%s= %d",s,k);
else sprintf(text,"%s= xxx",s);
int wt = textwidth(text);
int ht = textheight(text);
w+=wt;
outtextxy(x+(w-wt)/2,y+(h-ht)/2,text);
getch();
bar(x,y,x+w+1,y+h+1);
}

int Desk::dataError(int x,int y,int w,int h){ //ошибка
char text[]="Data Error";
int wt = textwidth(text);
int ht = textheight(text);
w+=wt;
int color = getcolor();
setcolor(RED);
rectangle(x,y,x+w,y+h);
outtextxy(x+(w-wt)/2,y+(h-ht)/2,text);
setcolor(color);
char ch;
do ch=getch();
while(ch!=13&&ch!=27);
bar(x,y,x+w+1,y+h+1);
return (ch=27)?1:0;
}

void Desk::Msg(int x,int y,int w,int h,char *s){//собщение
int wt = textwidth(s);
int ht = textheight(s);
w+=wt;
outtextxy(x+(w-wt)/2,y+(h-ht)/2,s);
getch();
bar(x,y,x+w+1,y+h+1);
}//
int Desk::str2int(char *str,int &result)//перевод в число
{
char correct=1,minus=0;
int res=0,i=0;
if (str[0] == -) {
minus = 1;
i = 1;
}
if (str[i] == 0) {
return 0;
}
while(correct&&(str[i]!=0)) {
if ((str[i] >= 0x30)&&(str[i] <= 0x39)) {
res = res*10 + (str[i] - 0x30);
} else {
correct = 0;
}
i++;
}
if (correct) {
result = (minus)?(-res):(res);
return 1;
} else {
return 0;
}
}
int Desk::numInput(int x, int y, int w, int h, char *prompt){//число
int ht, wt;
char text[2];
setbkcolor(BLUE);
wt = textwidth(prompt);
ht = textheight(prompt);
w+=wt;
outtextxy(x+(w-wt)/2,y+(h-ht)/2,prompt);
text[0] = getch(); text[1]=;
bar(x,y,x+w+1,y+h+1);
wt = textwidth(text);
ht = textheight(text);
outtextxy(x+(w-wt)/2,y+(h-ht)/2,text);
while(getch()!=13);
bar(x,y,x+w+1,y+h+1);
if(text[0]>=48&&text[0]<=57) return text[0]-48;
return 0;
}

void Desk::strInput(int x, int y, int w, int h, char *prompt, char *text, int limit){//строка
int ht, wt;
setbkcolor(BLUE);
wt = textwidth(prompt);
ht = textheight(prompt);
w+=wt;
outtextxy(x+(w-wt)/2,y+(h-ht)/2,prompt);
int i=0;
text[0]=;
while(((text[i++]=getch())!=13)&&(i<=limit)){
text[i]=;
bar(x,y,x+w+1,y+h+1);
w-=wt;
wt = textwidth(text);
ht = textheight(text);
w+=wt;
outtextxy(x+(w-wt)/2,y+(h-ht)/2,text);
}
text[i-1]=;
bar(x,y,x+w+1,y+h+1);
}

void Desk::PaintBg(){ //окно
setfillstyle(1,1);
bar(0,0,640,480);
setcolor(11);
rectangle(5,5,635,475);
}

void Desk::Go(){//команды
unsigned char ch;
for(;;){
ch = getch();
switch(ch){
case 13: Command(); break;
case 72: mn.Upward(); break;
case 75: mn.Backward(); break;
case 77: mn.Forward(); break;
case 80: mn.Downward(); break;
case 27: exit(0);
}
}
}

void Desk::Command(void){ ///команды
lbx2->Clear();
Menu *smn = mn.getSubMenu(mn.getSelected());
Menu *smn1 = NULL;
if(smn) smn1 = smn->getSubMenu(smn->getSelected());
switch(mn.getSelected()){
case 0: if(smn){
switch(smn->getSelected()){
case -1: smn->Show(); break;
case 0: setCount(); break;
case 1: Init(); break;

}
}
break;
case 1: if(smn){
switch(smn->getSelected()){
case -1: smn->Show(); break;
case 0: if(smn1){
switch(smn1->getSelected()){
case -1: smn1->Show(); break;
case 0: strclear(); break;
}
}
break;
case 1: if(smn1){
switch(smn1->getSelected()){
case -1: smn1->Show(); break;
case 0: sidToUpper(); break;
case 1: sidAssign(); break;
case 2: sidSub(); break;
case 3: Ind();break;
}
}
break;
case 2: if(smn1){
switch(smn1->getSelected()){
case -1: smn1->Show(); break;
case 0: sbtChangeChar(); break;
case 1: sbtAssign(); break;
case 2: sbtSub(); break;
case 3: sbtInd();break;
}
}
break;
case 3: break;
}
}
break;
case 2: exit(0);
}
}
Файл menu.h

#ifndef MENU_H
#define MENU_H

class MenuItem{
private:
int status;
int x, y, w, h;
char text[16];

public:
MenuItem();
MenuItem(int,int,int,int, char *);
void Show(void);
void Hide(void);
void setStatus(int);
int getStatus(void);
~MenuItem(){}
};

class Menu;

struct MItem{
MenuItem *item;
bool enabled;
Menu *submenu;
};

class Menu{
private:
Menu *supmenu;
MItem mItem[10];
int n;
int selected;
bool visible;

public:
Menu();
Menu(Menu *, int);
~Menu();
void Add(int,int,int,int,char *);
void setSubmenu(Menu *,int);
void Show(void);
void Hide(void);
void setSelect(int);
int getSelected(void);
void setEnable(int);
int isEnable(int);
void setDisable(int);
void Forward(void);
void Backward(void);
void Upward(void);
void Downward(void);
void setSubMenu(int, Menu *);
Menu *getSubMenu(int);
};

#endif /* MENU_H */
Файл Menu.cpp

#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<conio.h>
#include<graphics.h>
#include "menu.h"

MenuItem::MenuItem(){
status = 0;
x = 0; y = 0; w = 120; h = 30;
strcpy(text,"Item");
Show();
}

MenuItem::MenuItem(int xx,int yy,int ww,int hh, char *s){
status = 0;
x = xx; y = yy; w = ww; h = hh;
strncpy(text,s,16);
Show();
}

void MenuItem::setStatus(int k){
status = k;
Show();
}

int MenuItem::getStatus(){
return status;
}

void MenuItem::Show(void){
rectangle(x,y,x+w,y+h);
int clr = getcolor();
if(status > 0) setcolor(RED);
else if(status==0) setcolor(LIGHTGREEN);
else setcolor(LIGHTGRAY);
setbkcolor(BLUE);
int wt = textwidth(text);
int ht = textheight(text);
outtextxy(x+(w-wt)/2,y+(h-ht)/2,text);
setcolor(clr);
}

void MenuItem::Hide(void){
if(status==1) status = 0;
int clr = getcolor();
setcolor(BLUE);
bar(x,y,x+w+1,y+h+1);
setcolor(clr);
}

Menu::Menu(){
n=0;
selected=-1;
visible = 1;
supmenu = NULL;
for(int i=0;i<10;i++){
mItem[i].item = NULL;
mItem[i].submenu = NULL;
mItem[i].enabled = 1;
}
}

Menu::Menu(Menu *mn, int k){
n=0;
selected=-1;
visible = 1;
supmenu = mn;
for(int i=0;i<10;i++){
mItem[i].item = NULL;
mItem[i].submenu = NULL;
mItem[i].enabled = 1;
}
mn->setSubMenu(k,this);
}

Menu::~Menu(){
while(n>=0) delete mItem[--n].item;
}

int Menu::isEnable(int k){
return mItem[k].item->getStatus() >= 0;
}

void Menu::Add(int x,int y,int w,int h,char *s){
mItem[n++].item = new MenuItem(x,y,w,h,s);
return;
}

void Menu::setSubmenu(Menu *mn,int k){
if(k>=0&&k<n) mItem[k].submenu = mn;
mn->supmenu = this;
}

void Menu::Show(void){
for(int i=0;i<n;i++) mItem[i].item->Show();
visible = 1;
}

void Menu::Hide(void){
Menu *smn = NULL;
if(selected >=0) smn = mItem[selected].submenu;
if(smn) smn->Hide();
for(int i=0;i<n;i++) mItem[i].item->Hide();
selected = -1;
visible = 0;
}

void Menu::setSelect(int k){
if(mItem[k].enabled){
mItem[k].item->setStatus(1);
if(selected >=0) mItem[selected].item->setStatus(0);
selected = k;
}
}

void Menu::setEnable(int k){
if(k!=selected) mItem[k].item->setStatus(0);
mItem[k].enabled = 1;
Show();
}

void Menu::setDisable(int k){
if(k!=selected) mItem[k].item->setStatus(-1);
mItem[k].enabled = 0;
Show();
}

void Menu::Forward(void){
Menu *smn = NULL;
int i;
for(i=selected+1;i<n;i++) if(mItem[i].enabled) break;
if(i<=n-1){
mItem[i].item->setStatus(1);
if(selected>=0){
mItem[selected].item->setStatus(0);
smn = mItem[selected].submenu;
}
if(smn) { /*smn->selected = -1*/; smn->Hide(); }
selected = i;
}
}

void Menu::Backward(void){
int i;
for(i=selected-1;i>=0;i--) if(mItem[i].enabled) break;
if(i>=0){
mItem[i].item->setStatus(1);
mItem[selected].item->setStatus(0);
Menu *smn = mItem[selected].submenu;
if(smn) { /*smn->selected = -1*/; smn->Hide(); }
selected = i;
} else if(supmenu) {
selected = -1;
Hide();
}
}

void Menu::Upward(void){
Menu *mn = this, *mn1 = NULL;
while(mn->selected >=0 && (mn1=mn->mItem[mn->selected].submenu) && mn1->visible) mn = mn1;
mn->Backward();
}

void Menu::Downward(void){
Menu *mn = this, *mn1 = NULL;
while(mn->selected >=0 && (mn1=mn->mItem[mn->selected].submenu) && mn1->visible) mn = mn1;
mn->Forward();
}

void Menu::setSubMenu(int i, Menu *mn){
if(i>=0&&i<n) mItem[i].submenu = mn;
}

Menu *Menu::getSubMenu(int i){
if(i>=0&&i<n) return mItem[i].submenu;
return NULL;
}

int Menu::getSelected(void){
return selected;
}
Файл Listbox.h

#ifndef LISTBOX_H
#define LISTBOX_H

#ifndef STR_MAX
#define STR_MAX 255
#endif
#define STR_LEN 79
#define LINE_HEIGHT 20

class ListBox;

class ListItem {
private:
int x, y, w, h;
ListBox *lbx;
public:
char text[STR_LEN+1];
ListItem(void);
ListItem(int,int,int,int,char *);
~ListItem(void);
void setText(char *);
void Show(void);
void Erase(void);
};

class ListBox {
private:
int x, y, w, h;
int n;
ListItem *lItem[STR_MAX];

public:
ListBox(void);
ListBox(int,int,int,int);
~ListBox(void);
void Add(char *);
void AddSeveral(int);
void UpdateRow(int,char *);
void Clear(void);
void Show(void);
void Erase(void);
void Count(void);
};

#endif /* LISTBOX_H */
Файл Listbox.cpp
#include<cstdlib>
#include<cstdio>
#include<graphics.h>
#include "listbox.h"

ListItem::ListItem(){
x = 0; y = 0; w = 100; h = LINE_HEIGHT;
strcpy(text,"");
lbx = NULL;
}

ListItem::ListItem(int xx,int yy,int ww,int hh,char *s){
x = xx; y = yy; w = ww; h = hh;
strncpy(text,s,STR_LEN-1);
text[STR_LEN] = ;
lbx = NULL;
Show();
}

ListItem::~ListItem(){
Erase();
}

void ListItem::setText(char *s){
strncpy(text,s,STR_LEN+1);
if(strlen(s)>STR_LEN) text[STR_LEN+1] = ;
}

void ListItem::Show(){
Erase();
int clr = getcolor();
setcolor(BLUE);
rectangle(x,y,x+w,y+h);
setcolor(clr);
setbkcolor(BLUE);
int ht = textheight(text);
outtextxy(x+5,y+(h-ht)/2,text);
}

void ListItem::Erase(){
//int clr = getcolor();
//setcolor(BLUE);
bar(x,y,x+w-1,y+h);
//setcolor(clr);
}

ListBox::ListBox(){ //puts("ListBox()");
x = 0; y = 0; w = 200; h = 100;
n = 0;
for(int i=0;i<STR_MAX;i++) lItem[i] = NULL;
Show();
}

ListBox::ListBox(int xx,int yy,int ww,int hh){
char s[STR_LEN];
x = xx; y = yy; w = ww; h = hh;
n = 0;
Show();
}

ListBox::~ListBox(){ //puts("~ListBox()");
for(int i=0;i<n;i++) if(lItem[i]) delete lItem[i];
}

void ListBox::Add(char *s){
if(n<8){
lItem[n] = new ListItem(x+1, y+n*LINE_HEIGHT+1, w, LINE_HEIGHT,s);
n++;
}
}

void ListBox::AddSeveral(int k){
char s[1];
if(k>=0&&k<=STR_MAX){
for(int i=0;i<k;i++) {
sprintf(s,"%d",i+1);
lItem[i] = new ListItem(x+1, y+i*LINE_HEIGHT+1, w, LINE_HEIGHT,s);
n++;
}
}
}

void ListBox::UpdateRow(int k, char *text){ //printf("%d %s
",k,text);
lItem[--k]->setText(text);
lItem[k]->Show();
}

void ListBox::Clear(){
for(int i=0;i<n;i++) delete lItem[i];
n=0;
}

void ListBox::Erase(){
for(int i=0;i<n;i++) lItem[i]->Erase();
}

void ListBox::Show(){
rectangle(x,y,x+w,y+h);
}

void ListBox::Count(){
printf("n=%d
",n);
}

Файл main.cpp

#include<cstdlib>
#include<graphics.h>
#include "desk.h"

void *ptr = NULL;

int main(void){
int gd = DETECT, gm;
initgraph(&gd, &gm, "");
Desk dsk;
dsk.Go();
system("pause");
closegraph();
return 0;
}




Изображения