- •Федеральное агенство по образованию
- •Оглавление
- •Массивы указателей на строки Задание 1. Текстовый редактор Задание 1.1 Динамическая память. Модульное программирование
- •Задание 1.2 Реализация таблицы на основе динамического массива
- •Задание 1.3 Специальные функции работы со строками
- •Задание 1.3 Разработка приложенияWindowsForms
- •Структуры Задание 2 Реализация текстового редактора с использованием структур данных Задание 2.1 Представления набора строк в виде структур данных
- •Задание 2.2 Реализация операций выборки, преобразования и сортировки наборов строк с использованием словаря данных
- •Задание 3. Информационная система
- •Задание 3.1 Модульное программирование
- •Задание 3.2 Работа с и динамической памятью
- •Задание 3.3 Ввод и вывод
- •Пример реализации для консольного приложения
- •Пример реализации для приложения с оконным графическим интерфейсом
- •Задание 3.4 Сравнение структур
- •Задание 3.5 Консольное приложение
- •Задание 3.5 Приложение WindowsForms
- •3.6 Пример пошаговой разработки приложение WindowsForms
- •Классы. Задание 4. Объектно-ориентированная реализация текстового редактора
- •Задание 4. 1 Разработка класса классаMyString.
- •Задание 4. 2 Разработка класса таблица.
- •Задание 5. Объектно-ориентированная реализация информационной системы Задание 5.1 Представление структуры данных записи (Record), в виде класса с конструкторами и деструкторами
- •Задание 5. 2 Разработка класса таблица для хранения объектов классаRecord.
- •Задание 5.3 Представление базовых понятий предметной области в виде классов. Разработка интерфейса и реализации. Определение конструкторов классов.
- •1. Разработать класс MyDate (дата-время)
- •3. Дополнить класс MyString (строка)
- •4. Разработать класс Title (название)
- •5 . Разработать класс Name (имя)
- •6. Разработать класс Address (Адрес)
- •7. Разработать класс Telephone ( номер телефона)
- •8. Разработать класс e_Mail (Адрес электронной почты)
- •Задание 5.2 Использование объектов классов в качестве элементов классов
- •Задание 5.3 Использование указателей на объекты классов и объекты классов в качестве элементов классов
- •Задание 5.4 Система управления данными.
- •Задание 5.5 Иерархия классов
- •Задание 5.6 Шаблоны классов
- •Приложение 1
- •Приложение 2
- •Приложение 3
- •В среде разработки Visual Studio .Net (массивы строк, структуры, классы)
Задание 3.5 Консольное приложение
#include "stdafx.h"
#include "Tabl.h"
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{ Tabl* t=0; t=init(t,100);
T buf1=0; buf1=init(buf1);
T buf2=0; buf2=init(buf2);
//далее код, аналогичный программе тестирование функций работы со строками из задания 1, //т.е. меню, каждый пункт которого служит для вызова соответствующей функции.
// новые пункты меню
case'7':
{ struct ParamSort p;
p.DirectCond[0]=1; p.DirectCond[1]=0; p.DirectCond[2]=1;
p.FieldName[0]="title"; p.FieldName[1]="price";p.FieldName[2]="year";
Compare Comp ={(void*)&p,CmpParam};
sort(t,Comp); break;}
case '8':
{ foutput(t,"dat.txt"); break;}
case '9':
{ finput(t,"dat.txt"); break;}
case 'a':
{int Max,Min;
cout<<"input Min price\n";cin>>Min;
cout<<"input Max price\n";cin>>Max;
cin.get(endline);
struct InRange r;
r.MinValue=Min;
r.MaxValue=Max;
Predicate pred={(void*)&r,InRangePrice};
Tabl*q= Query(t, pred);
cout<<" elements : "<<endl; output(q);break;}
}
}while(c!='0');
dispose(t);
return0;
}
}
Возможно появление ошибок при компиляции, связанных с использованием константных ссылок (const T& item), когда типом T является указатель . В этом случае вместо константных ссылок необходимо использовать передачу параметров по значению (T item).
Задание 3.5 Приложение WindowsForms
Интерфейс программы имеет следующий вид:
Исполнение каждой операции начинается после нажатия соответствующей командной кнопки на форме. Команды меню дублируют кнопки на форме. Ввод данных для формирования записей и условий поиска производится с помощью текстовых полей textBox. Для конвертирования типа данныхString* в тип данныхchar*можно использовать функции модуляMyConvert. Просмотр всех записей и результатов выполнения запросов производится с помощью спискаlistView.
В программе должно быть предусмотрено использование стандартных диалогов Windowsдля сохранение всех записей в файл и чтение из файла.
3.6 Пример пошаговой разработки приложение WindowsForms
Создайте новый проект по шаблону WindowsForms.
Далее в проект необходимо добавить все модули,разработанные в консольном приложении, такие как модули , описывающие запись , таблицу ,а также модуль функций преобразования MyConvert, дополненный функциями, работающими с типомSystem::String.
Файл MyConvert.h
int copyto(char** ss,char buf[] );
int copyto(int* i,char buf[]);
int copyto(double* d,char buf[]);
int copyto(char* buf,String* S,int count);
int copyto(char** str,String* S);
int copyto(TextBox* m[],String* s[],int count,int first_s=0,int first_m=0);
Файл реализации MyConvert.cpp
//…
int copyto(char* buf,System::String* S,int count)
{int i, state;
for(i=0;i<S->Length;i++){
if(i>=count) break;
wchar_t t=S->Chars[i];
state=WideCharToMultiByte(CP_ACP, 0, &t, 1, &buf[i], 1, NULL, NULL);
}
buf[i]='\0';
return state;}
int copyto(char** str,System::String* S)
{ delete [](*str);
*str=new char [S->Length+1];
return copyto(*str,S, S->Length);
}
int copyto(TextBox* m[],String* s[],int count,int first_s,int first_m)
{ if(s==0)return 0;
while(count-->0)
m[first_m++]->Text=s[first_s++];
return 1;
}
Необходимо полностью изменить реализацию модуля исключений, используя для вывода сообщений функцию оконного графического интерфейса MessageBox::Show
void ExeptionLetters(char* str)
{String* s=new String(str);
s=String::Concat(S"\nString\t",s,S"\t must include inglish letters\n");
MessageBox::Show(s,S"ExeptionLetters ");}
void ExeptionInt(char* str)
{String* s=new String(str);
s=String::Concat(S"\nString\t",s,S"\t must include letters of digits\n");
MessageBox::Show(s,S"ExeptionInt ");}
void ExeptionFloat(char* str){}
void ExeptionRange(double d,double min,double max)
{String* s1=d.ToString();
String* s2=min.ToString();
String* s3=max.ToString();
s1=String::Concat(S"\n Value\t",s1,S"\t must be latter then ",s2,S"and must be greater then",s3);
MessageBox::Show(s1,S"ExeptionRange");}
void ExeptionFopen(char* str)
{String* s=new String(str);
s=String::Concat(S"\nFile\t",s,S"\t open error\n");
MessageBox::Show(s,S"ExeptionFopen");}
void ExeptionFound()
{MessageBox::Show("Просмотр закончен. Искомый элемент не найден"
,"Поиск");}
void ExeptionEmpty()
{MessageBox::Show("Поля ввода не должны быть пустыми"
,"Input");}
Модуль функций ввода – вывода (io.h,io.cpp) необходимо дополнить функциями ввода из текстовых редакторов
using namespace System;
using namespace System::Windows::Forms;
int input(TextBox * t,char* s,int count)
{return copyto(s,t->Text,count);
}
int input(TextBox * t,char** s)
{ return input( t,buf,MAX) && copyto(s,buf); }
int input(TextBox * t,int *i)
{return input( t,buf,MAX) && copyto(i,buf);}
Модуль функций (Record.h , Record .cpp) необходимо дополнить функциями ввода – вывода, работающими с системными типами System::String, TextBox, ListView
Record.h
copyto(String* m[],Record* r, int first=0);
int input (TextBox* m[],Record* r, int first=0) ;
void output(TextBox* m[],Record* r, int first=0);
void output(ListView*list, Record* r);
Record .cpp
int input(TextBox* m[],Record*rr,int first)
{int state=1;
if(rr)
{state&=input(m[first++], rr->autor,10) ;
state&=input(m[first++],&rr->title) ;
state&=input(m[first++],&rr->number) ;
state&=input(m[first++],&rr->price) ;
state&=input(m[first++],&rr->day) ;
state&=input(m[first++],&rr->month) ;
state&=input(m[first++],&rr->year ) ;
state&=validate(rr) ;
}
return state;}
void copyto(String* m[],Record* r,int first)
{if(!r)return;
m[first++]=new String(r->autor);
m[first++]=new String(r->title);
m[first++]=r->number.ToString();
m[first++]=r->price.ToString();
m[first++]=r->day.ToString();
m[first++]=r->month.ToString();
m[first++]=r->year.ToString();
}
void output(TextBox* m[],Record* r,int first)
{String* s[]=new String*[7];
copyto(s,r);
copyto(m,s,7,first,0);
}
void output(ListView*list,Record* r)
{ String* s[]=new String*[7];
copyto(s,r);
list->Items->Add(new ListViewItem(s));
}
Модуль (Tabl.h, Tabl .cpp) необходимо дополнить функцией вывода таблицы в компонент ListView
void output(ListView*list,Tabl* t)
{list->Items->Clear();
for(T* i=begin(t);i!=end(t);i++)
output(list,*i);
}
В файл Form1.h при помощи директивы #include подключить заголовочные файлы этих модулей. Например
#pragma once
#include "stdafx.h"
#include "exeptions.h"
#include "MyConvert.h"
#include “ io.h”
#include "chars.h"
#include "Record.h"
#include "Tabl.h"
#include "FQuery2.h"
#include "Sort.h"
в пространстве имен приложения необходимо определить вспомогательные переменные
namespace Book_Lib_Stuct_2003
{T _current,_found;
В классе формы после функции
void InitializeComponent(void)
{...}
необходимо определить вспомогательные переменные
public:
Tabl* t;
TextBox* m[];
int _foundNext, flag, SelectIndex;
char* FileName;
Выделение памяти под таблицу и инициализация вспомогательных переменных осуществляется в обработчике события загрузки формы, который необходимо предварительно создать при помощи окна свойств и вкладки событий (Events)
private: System::Void Form1_Load(System::Object * sender, System::EventArgs * e)
{ t=0; _current=0;_found =0;
t=init(t,100);
_current=init(_current); _found=init(_found );
_foundNext=-1;flag=0;
m=new TextBox*[7];
m[0]=textBox1;m[1]=textBox2;m[2]=textBox4; m[3]=textBox3 ;
m[4]=textBox11;m[5]= textBox9; m[6]=textBox10;
}
Код занесения данных в таблицу выглядит следующим образом
private: System::Void Insert_Click(System::Object * sender, System::EventArgs * e)
{ if(!input( m,_current)) {ExeptionEmpty();return;}
insert(t,_current);
output(listView1,t);
}
Поиск
Поиск организуется при помощи обработчиков событий двух кнопок Find и FindNext
Индекс найденного элемента сохраняется в вспомогательной переменной _foundNext. Поиск следующего элемента организуется, начиная с позиции _foundNext+1. Элементы сравниваются по заполненным текстовым полям. Они сохраняются в структурной переменной _found. Все поля найденного элемента выводятся в окна текстовых редакторов TextBox
private: System::Void Find_Click(System::Object * sender, System::EventArgs * e)
{ input( m,_found);
_foundNext=find(t,0,_found);
if( _foundNext!=-1)
output( m,*(begin(t)+_foundNext));
else { ExeptionFound(); }
}
private: System::Void FindNext_Click(System::Object * sender, System::EventArgs * e)
{if(_foundNext==-1) return;
_foundNext=find(t,_foundNext+1,_found);
if( _foundNext!=-1)
output( m,*(begin(t)+_foundNext));
else {ExeptionFound(); }
}
Выполнение запросов.
Программа должна выполнять несколько запросов для поиска набора записей , удовлетворяющих произвольным критериям поиска. В отличии от функции поиска функция, выполняющая запрос, возвращает не одну запись, а весь набор записей, удовлетворяющих заданному условию, в виде таблицы. Ввод параметров для поиска осуществляется с помощью собственной формы
Пример 1. Совпадение значения поля со строковым параметром
struct Param1{
char* Value;
};
bool _f1(Record*t, void*p0)
{Param1 *p=(Param1 *)p0;
return strcmp(t->title,p->Value)==0;
}
Пример 2. Нахождение числового поля в заданном интервале значений
struct InRange{
int MinValue,MaxValue;
};
bool InRangePrice(Record* item, void* param)
{InRange *p=(InRange *)param;
return (item->price-p->MinValue)>=0 && (item->price-p->MaxValue)<=0;
}
В заголовочный файл формы запроса FQuery2 необходимо добавить следующий код
struct InRange*p;
public: void getParam(InRange*pp)
{p=pp;}
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{ p->MinValue=Convert::ToInt32(textBox1->Text);
p->MaxValue=Convert::ToInt32( textBox2->Text);
this->Close();
}
Реализация функции, выполняющий запрос, выглядит следующим образом
Tabl* Query(Tabl*t, Predicate& pred)
{Tabl*rez=init(t,24);
T* i;
for( i= begin(t); i!=end(t);i++)
if(pred.fun(*i))
insert(rez,*i);
return rez;
}
В файле главной формы (Form1) необходимо определить функцию, которая открывает окно ввода параметров и выполняет запрос, результат запроса выводит в список
private: System::Void Query2_Click(System::Object * sender, System::EventArgs * e)
{struct InRange p;
FQuery2 *form= new FQuery2;
form->getParam(&p);
form->ShowDialog();
Predicate pred={(void*)&p,(Pr)&InRangePrice};
Tabl*q= Query(t, pred);
output(listView1,q);
}
Для большого количества запросов удобно определить массив объектов класса Predicateи инициализировать его соответствующими значениями с помощью одной функции
typedef Predicate* AllPred[] ;
AllPred InitAllPred( )
{AllPred All=new Predicate*[2];
All[0]=new Predicate;
Param1 *p1=new Param1;
All[0]->param=(void*)p1;
All[0]->f=_f1;
All[1]=new Predicate;
Param2 *p2=new Param2;
All[1]->param=(void*)p2;
All[1]->f=InRangePrice;
return All;}
Тогда словесное описание запросов можно поместить в список и вызов запроса осуществлять на основе индекса, выбранного элемента списка.
private: System::Void button2_Click(System::Object * sender, System::EventArgs * e)
{ExecQuery(All[listBox1->SelectedIndex]);
}
Сортировка
void sort (Tabl* t, Compare& comp);
Данные для сортировки передаются через аргумент, являющийся объектом класса Compare.
struct Compare{
void* param;
Cmp f;
int cmp( Record* a, Record* b)
{return (*f)(a,b,param);}
};
Класс содержит указатель на функцию, сравнивающую два элемента таблицы. Тип указателя определяется следующим образом
typedefbool(*Cmp)(constT&,constT&,void*param);
Сортировка проводится по произвольным выбранным трем полям как по возрастанию , так и по убыванию. Приоритет сортировки среди трех полей для оконного приложения задается в отдельном диалоговом окне.
Эти данные сохраняются в виде структуры
class ParamSort {
public:
char* FieldName[3];
intDirectCond[3];
};
В заголовочный файл формы сортировки необходимо добавить следующий код
public:
struct ParamSort *p;
void getParam(ParamSort *pp)
{p=pp;}
private: System::Void button1_Click(System::Object * sender, System::EventArgs * e)
{ String*s;
s=Convert::ToString(comboBox1->SelectedItem);
copyto(p->FieldName[0], s);
s=Convert::ToString(comboBox2->SelectedItem);
copyto(p->FieldName[1], s);
s=Convert::ToString(comboBox3->SelectedItem);
copyto(p->FieldName[2], s);
p->DirectCond[0]=(radioButton1->Checked)?1:0;
p->DirectCond[1]=(radioButton4->Checked)?1:0;
p->DirectCond[2]=(radioButton6->Checked)?1:0;
this->Close();
}
В файле главной формы (Form1) необходимо определить функцию, которая открывает окно ввода параметров и выполняет сортировку
private: System::Void Sort_Click(System::Object * sender, System::EventArgs * e)
{struct ParamSort p;
TSort *form= new TSort;
form->getParam(&p);
form->ShowDialog();
Compare Comp ={(void*)&p,CmpParam};
sort(t,Comp);
output(listView1,t);
}