Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Задание С++ 07_10_08_.doc
Скачиваний:
25
Добавлен:
11.03.2016
Размер:
1.15 Mб
Скачать

Задание 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

  1. Создайте новый проект по шаблону WindowsForms.

  2. Далее в проект необходимо добавить все модули,разработанные в консольном приложении, такие как модули , описывающие запись , таблицу ,а также модуль функций преобразования 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;

}

  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");}

  1. Модуль функций ввода – вывода (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);}

  1. Модуль функций (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));

}

  1. Модуль (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);

}

  1. В файл 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;

  1. Выделение памяти под таблицу и инициализация вспомогательных переменных осуществляется в обработчике события загрузки формы, который необходимо предварительно создать при помощи окна свойств и вкладки событий (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;

}

  1. Код занесения данных в таблицу выглядит следующим образом

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);

}