- •1 Постановка задачі
- •2 Розробка програми
- •2.1 Аналіз вхідних та вихідних даних
- •2.2 Методи та засоби програмування
- •2.3 Опис логічної структури програми
- •2.4 Опис фізичної структури програми
- •2.5 Інструкція користувача програми
- •2.6 Вимоги до складу та параметрів технічних та програмних засобів
- •2.7 Тестування програми
- •2.8 Результати реалізації програми
- •2.9 Висновки
- •3. Перелік використаних джерел
- •4. Додатки
2.8 Результати реалізації програми
Програма, розроблена у курсовому проекті, у повному обсязі ви-конує поставлені задачі, а саме – створення фігур - кругів та еліпсів та робота з ними, за допомогою ієрархії класів «Figure», «Circle» та «Elipse».
Додатковою особливістю програми є: сортування колекції та пошук елементу колекції по заданому користувачем критерії в контейнері.
Вдосконалити програму можна, структурувавши вже реалізовані дії над фігурами, такі як:
– збереження у файл: додати можливість створювати декілька різних файлів роботи з фігурами;
– завантаження з файлу: надати можливість вибирати, який саме файл з фігурами завантажити для роботи.
2.9 Висновки
В цьому курсовому проекті були розроблені три класи обробки даних о фігурах, також складена тестова програма перевірки їх працеспроможності.
За час виконання курсового проекту я досконально вивчив принцип роботи з абстрактними типами даних, принципами роботи з програмними одиницями, перевантаженням операторів та функцій, ітераторами, послідовними контейнерами та файловими потоками. Ознайомився зі стандартними бібліотечними файлами мови С++.
Розроблені класи та тестову програму можна використовувати для збереження бази даних набору фігур.
3. Перелік використаних джерел
Глушаков С.В., Коваль А.В., Смирнов С.В. «Язык программирования С++», - Харьков: Фолио, 2002 – 550с.
Л.И.Климова «С++. Практическое программирование. Решение типовых задач», - М.:КУДИЦ-ОБАЗ, 2001. – 543с.
Р.Лафоре Объектно-ориентированное программирование в С++, - Питер, 2004
С. Окулов, «Программирование в алгоритмах», - : Бином. Лаборатория знанй, 2007 – 334с.
Н.Культин «С/С++ в задачах и примерах», СПБ.: БВХ, 2003. – 167с.
Т.А. Павловская «С/С++ на высоком уровне», - СПБ.: Питер, 2001. – 786с.
4. Додатки
Додаток А
Алгоритми методів
Додаток Б
Лістинг програми
Source.cpp:
#include "Header.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#pragma warning (disable: 4996)
void main(){
Programm *programm;
programm = new Programm();
programm->init();
programm->run();
programm->done();
}
Header.h: #include <iostream>
#include <fstream>
#include <deque>
#include <string>
using namespace std;
class Figure abstract{
protected:
float xCenter;
float yCenter;
float angle;
float scaleFactor;
bool visible;
public:
Figure();
Figure(float _xCenter, float _yCenter, float _angle, float _scaleFactor);
virtual void show() abstract;
virtual void input() abstract;
virtual void hide() abstract;
virtual void unHide() abstract;
virtual void rotateBy(float angle) abstract;
virtual void moveBy(float x, float y) abstract;
float getXCenter();
float getYCenter();
float getAngle();
float getScaleFactor();
friend ostream &operator<<( ostream &output, Figure &f );
friend string &operator>>( string &line, Figure &f );
};
class Circle : public Figure {
public:
Circle();
Circle(float xCenter, float yCenter, float angle, float scaleFactor);
void show() override;
void hide() override;
void unHide() override;
void rotateBy(float angle) override;
void moveBy(float x, float y) override;
void input() override;
};
class Elipse : public Figure {
public:
Elipse();
Elipse(float xCenter, float yCenter, float angle, float scaleFactor);
void show() override;
void hide() override;
void unHide() override;
void rotateBy(float angle) override;
void moveBy(float x, float y) override;
void input() override;
};
class Programm {
private:
typedef deque<Figure*> MyCollection;
MyCollection* collection;
public:
void init();
void run();
void done();
void createCircle();
void createEllipse();
void showAllElements();
void showAllElements(deque<Figure*> *elements);
void deleteAllElements();
Figure* createCircleManually();
Figure* createEllipseManually();
int writeFigures(deque <Figure*> &figures);
int readFigures(deque <Figure*> &figures);
void save();
void load();
void sort();
void find();
void requestsMenu();
};
AdditionalSource.cpp:
#include "Header.h"
#include <algorithm>
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;
Figure::Figure(){
xCenter = 0;
yCenter = 0;
angle = 0;
scaleFactor = 0;
visible = true;
}
Figure::Figure(float _xCenter, float _yCenter, float _angle, float _scaleFactor){
xCenter = _xCenter;
yCenter = _yCenter;
angle = _angle;
scaleFactor = _scaleFactor;
visible = true;
}
float Figure::getXCenter(){
return xCenter;
}
float Figure::getYCenter(){
return yCenter;
}
float Figure::getAngle(){
return angle;
}
float Figure::getScaleFactor(){
return scaleFactor;
}
string dotsToCommasFloat(float value){
string s;
s = to_string(value);
replace(s.begin(), s.end(), '.', ',');
return s;
}
string replaceComasToDots(string &s){
replace(s.begin(), s.end(), '.', ',');
return s;
}
string сonvert (float number){
std::ostringstream buff;
buff<<number;
return buff.str();
}
ostream& operator<<( ostream& os, Figure& f ){
os << "\t" << dotsToCommasFloat(f.xCenter) << "\t" << dotsToCommasFloat(f.yCenter) << "\t"
<< dotsToCommasFloat(f.angle) << "\t" << dotsToCommasFloat(f.scaleFactor) << endl;
return os ;
}
string getStringAfterCimbol(std::string &s, char c) {
string::size_type pos = s.find(c);
if (pos != string::npos)
return s.substr(pos+1, s.length());
else
return s;
}
string& operator>>(string& line, Figure& f){
string subStr;
subStr = line.substr(0, line.find('\t'));
line.erase(0, line.find('\t')+1);
f.xCenter = atof(subStr.c_str());
subStr = line.substr(0, line.find('\t'));
line.erase(0, line.find('\t')+1);
f.yCenter = atof(subStr.c_str());
subStr = line.substr(0, line.find('\t'));
line.erase(0, line.find('\t')+1);
f.angle = atof(subStr.c_str());
subStr = line.substr(0, line.find('\t'));
f.scaleFactor = atof(subStr.c_str());
return line;
}
Circle::Circle()
: Figure(){
};
Circle::Circle(float _xCenter, float _yCenter, float _angle, float _scaleFactor)
: Figure(_xCenter, _yCenter, _angle, _scaleFactor){
};
void Circle::hide(){
visible = false;
}
void Circle::unHide(){
visible = true;
}
void Circle::rotateBy(float _angle){
angle+=_angle;
}
void Circle::moveBy(float x, float y){
xCenter+=x;
yCenter+=y;
}
void Circle::show(){
int fieldW = 12;
cout << setw(fieldW) << left << "Circle";
if (visible) {
cout << setw(fieldW) << left << xCenter
<< setw(fieldW) << left << yCenter
<< setw(fieldW) << left << angle
<< setw(fieldW) << left << scaleFactor
<< endl;
} else {
cout << setw(fieldW) << left << "invisible" << endl;
}
}
char* dotsToCommasChar(char *c, int N){
for (int i=0; i < N; i++){
if (c[i] == '.')
c[i] = ',';
}
return c;
}
void Circle::input(){
char s[10];
cout << "Введите xCenter: "; cin.getline(s,10); xCenter=atof(dotsToCommasChar(s, 10));
cout << "Введите yCenter: "; cin.getline(s,10); yCenter=atof(dotsToCommasChar(s, 10));
cout << "Введите angle: "; cin.getline(s,10); angle=atof(dotsToCommasChar(s, 10));
cout << "Введите scaleFactor: "; cin.getline(s,10); scaleFactor=atof(dotsToCommasChar(s, 10));
}
Elipse::Elipse()
: Figure(){
};
Elipse::Elipse(float _xCenter, float _yCenter, float _angle, float _scaleFactor)
: Figure(_xCenter, _yCenter, _angle, _scaleFactor){
};
void Elipse::hide(){
visible = false;
}
void Elipse::unHide(){
visible = true;
}
void Elipse::rotateBy(float _angle){
angle+=_angle;
}
void Elipse::moveBy(float x, float y){
xCenter+=x;
yCenter+=y;
}
void Elipse::show(){
int fieldW = 12;
cout << setw(fieldW) << left << "Ellipse";
if (visible) {
cout << setw(fieldW) << left << xCenter
<< setw(fieldW) << left << yCenter
<< setw(fieldW) << left << angle
<< setw(fieldW) << left << scaleFactor
<< endl;
} else {
cout << setw(fieldW) << left << "invisible" << endl;
}
}
void Elipse::input(){
char s[10];
cout << "Введите xCenter: "; cin.getline(s,10); xCenter=atof(dotsToCommasChar(s, 10));
cout << "Введите yCenter: "; cin.getline(s,10); yCenter=atof(dotsToCommasChar(s, 10));
cout << "Введите angle: "; cin.getline(s,10); angle=atof(dotsToCommasChar(s, 10));
cout << "Введите scaleFactor: "; cin.getline(s,10); scaleFactor=atof(dotsToCommasChar(s, 10));
}
void Programm::init(){
setlocale(LC_ALL, "Russian");
collection = new MyCollection;
cout << "Объекты успешно инициализированы" << endl;
system("pause");
}
void title(string s){
cout<<" <<" + s + ">> "<<endl;
}
void Programm::run(){
int i;
char s[10];
do {
system("cls");
title("ГЛАВНОЕ МЕНЮ");
cout<<"<Выберите пункт меню>"<<endl;
cout<<"<1>.Создать объект-круг"<<endl;
cout<<"<2>.Создать объект-эллипс"<<endl;
cout<<"<3>.Просмотреть список всех фигур"<<endl;
cout<<"<4>.Очистить список всех фигур"<<endl;
cout<<"<5>.Сохранить в файле"<<endl;
cout<<"<6>.Загрузить из файла"<<endl;
cout<<"<7>.Отсортировать объекты в контейнере"<<endl;
cout<<"<8>.Выполнить поиск"<<endl;
cout<<"<9>.Выполнить запрос"<<endl;
cout<<"<10>.Выход в WINDOWS"<<endl<<endl;
cout<<"Выбранный пункт меню:";
cin.getline(s,10);
i=atoi(s);
switch(i){
case 1:
system("cls");
title("Создание объекта круга");
createCircleManually();
cout<< "Объект-успешно создан" << endl;
system("pause");
break;
case 2:
system("cls");
title("Создание объекта-эллипса");
createEllipseManually();
cout<< "Объект-успешно создан" << endl;
system("pause");
break;
case 3:
system("cls");
title("Просмотр всех елементов");
cout << endl;
showAllElements();
system("pause");
break;
case 4:
system("cls");
title("Удаление списка всех елементов");
deleteAllElements();
cout<< "Список теперь пуст..." << endl;
system("pause");
break;
case 5:
system("cls");
title("Сохранение в файл");
save();
system("pause");
break;
case 6:
system("cls");
title("Загрузка объектов из файла");
load();
system("pause");
break;
case 7:
system("cls");
title("Сортировка объектов");
sort();
system("pause");
break;
case 8:
system("cls");
title("Поиск елементов");
find();
system("pause");
break;
case 9:
system("cls");
title("Выполнение запросов");
requestsMenu();
system("pause");
break;
default:if(i>10 || i<1) {cout<<"Вводите значения от 1 до 10"<<endl; system("pause"); break;}
}
}
while (i!=10);
}
void Programm::createCircle(){
Figure* f;
cout << "" << endl;
float xCenter = 10;
float yCenter = 5.25;
float angle = 90;
float scaleFactor = 2;
f = new Circle(xCenter, yCenter, angle, scaleFactor);
collection->push_back(f);
}
void Programm::createEllipse(){
Elipse* f;
cout << "" << endl;
float xCenter = 15;
float yCenter = 3.65;
float angle = 45;
float scaleFactor = 1.5;
f = new Elipse(xCenter, yCenter, angle, scaleFactor);
collection->push_back(f);
}
void Programm::showAllElements(){
showAllElements(collection);
}
void Programm::showAllElements(deque<Figure*> *elements){
if (elements->size() == 0){
cout << "Список пуст" << endl;
return;
}
int fieldW = 12;
cout << setw(fieldW) << left << "Номер"
<< setw(fieldW) << left << "Тип"
<< setw(fieldW) << left <<"центр по X"
<< setw(fieldW) << left << "центр по Y"
<< setw(fieldW) << left << "Угол"
<< setw(fieldW) << left << "Масштаб"
<< endl;
cout << "------------------------------------------------------------------" << endl;
for (int i = 0; i < elements->size(); i++){
cout << "<" << i+1 << ">" << setw(fieldW-3) << left <<".";
elements->at(i)->show();
//cout << *collection->at(i);
}
}
Figure* Programm::createCircleManually(){
Figure* f;
f = new Circle();
f->input();
collection->push_back(f);
return f;
}
Figure* Programm::createEllipseManually(){
Figure* f;
f = new Elipse();
f->input();
collection->push_back(f);
return f;
}
void Programm::deleteAllElements(){
collection->clear();
if (collection->empty())
cout << "Список полностью очищен" << endl;
else
cout << "Что то пошло не так..." << endl;
}
void Programm::done(){
collection->clear();
delete collection;
cout << "Вся память освобождена" << endl;
}
void Programm::save(){
cout<<"<<<Сохранение коллекции>>>"<<endl;
int l=writeFigures(*collection);
cout<<"Сохранено объектов: "<<l<<endl;
}
void Programm::load() {
int l=readFigures(*collection);
cout<<"Прочитано объектов: "<<l<<endl;
}
int Programm::writeFigures(deque <Figure*>& figures){
int count = 0;
ofstream out("figures.dat");
deque<Figure*>::iterator it = figures.begin();
for (it; it < figures.end(); it++){
if(typeid(*(*it))==typeid(Circle)){
out << "C"; //записываем в файл 1
//Выполняем сериализацию объекта Circle
out <<(*((Circle*)(*it))); count++;
}
if(typeid(*(*it))==typeid(Elipse)){
out << "E"; //записываем в файл 2
//Выполняем сериализацию объекта Elipse
out <<(*((Elipse*)(*it))); count++;
}
}
return count;
}
int Programm::readFigures(deque <Figure*> &figures){
//Создаем поток и открываем его для чтения
ifstream in("figures.dat");
Circle* c;
Elipse* e;
int count=0;
string line;
string objType;
//Пока не конец файла выполнять
do {
//Прочитать признак типа объекта
getline(in, line);
objType = line.substr(0, 1);
line.erase(0, line.find('\t')+1);
if(objType == "C"){//Это объект Cirle
c = new Circle();
line >> (*c);
figures.push_back(c);
count++;
}
if(objType == "E"){//Это объект Elipse
e = new Elipse();
line >> (*e);
figures.push_back(e);
count++;
}
} while (!in.eof());
return count;
}
struct CmpXCenterDec {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getXCenter() > f2->getXCenter());
}
} cmpXCenterDec;
struct CmpXCenterInc {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getXCenter() < f2->getXCenter());
}
} cmpXCenterInc;
struct CmpYCenterDec {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getYCenter() > f2->getYCenter());
}
} cmpYCenterDec;
struct CmpYCenterInc {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getYCenter() < f2->getYCenter());
}
} cmpYCenterInc;
struct CmpAngleDec {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getAngle() > f2->getAngle());
}
} cmpAngleDec;
struct CmpAngleInc {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getAngle() < f2->getAngle());
}
} cmpAngleInc;
struct CmpScaleFactorDec {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getScaleFactor() > f2->getScaleFactor());
}
} cmpScaleFactorDec;
struct CmpScaleFactorInc {
bool operator() (Figure *f1, Figure *f2) {
return (f1->getScaleFactor() < f2->getScaleFactor());
}
} cmpScaleFactorInc;
void Programm::sort(){
cout << "Выберите поле, по которому будет производиться сортировка:" << endl;
cout << "<1> Центр по Х" << endl
<< "<2> Центр по У" << endl
<< "<3> Угол" << endl
<< "<4> Масштаб" << endl;
int fieldType;
cin >> fieldType;
cout << "По возрастанию или убыванию? (0 - возрастание/ 1 - убывание)";
int sortType;
cin >> sortType; cout << endl;
switch (fieldType){
case 1:
if (sortType == 0)
std::sort(collection->begin(), collection->end(), cmpXCenterInc);
else if (sortType == 1)
std::sort(collection->begin(), collection->end(), cmpXCenterDec);
break;
case 2:
if (sortType == 0)
std::sort(collection->begin(), collection->end(), cmpYCenterInc);
else if (sortType == 1)
std::sort(collection->begin(), collection->end(), cmpYCenterDec);
break;
case 3:
if (sortType == 0)
std::sort(collection->begin(), collection->end(), cmpAngleInc);
else if (sortType == 1)
std::sort(collection->begin(), collection->end(), cmpAngleDec);
break;
case 4:
if (sortType == 0)
std::sort(collection->begin(), collection->end(), cmpScaleFactorInc);
else if (sortType == 1)
std::sort(collection->begin(), collection->end(), cmpScaleFactorDec);
break;
default:
break;
}
cout << "Отсортировано!" << endl << endl;
showAllElements();
}
void Programm::find(){
char s[10];
float tmp1 = -1;
float tmp2 = -1;
cout << "Выберите поле, по которому будет производиться поиск: " << endl;
cout << "<1> Центр по Х" << endl
<< "<2> Центр по У" << endl
<< "<3> Угол" << endl
<< "<4> Масштаб" << endl
<< "<5> Все поля" << endl
<< "<6> Тип фигуры (C/E)" << endl;
int fieldType;
cin.getline(s,10); fieldType = atoi(s);
cout << "Введите значение для поиска: ";
string val; cin.getline(s, 10);
val = s;
val = replaceComasToDots(val);
deque<Figure*> *findedFigures;
findedFigures = new deque<Figure*>;
for (int i = 0; i < collection->size(); i++){
Figure *f = collection->at(i);
bool isEqual = false;
switch (fieldType) {
case 1:
tmp1 = f->getXCenter();
tmp2 = atof(val.c_str());
isEqual = (tmp1 == tmp2);
break;
case 2:
tmp1 = f->getYCenter();
tmp2 = atof(val.c_str());
isEqual = (tmp1 == tmp2);
break;
case 3:
tmp1 = f->getAngle();
tmp2 = atof(val.c_str());
isEqual = (tmp1 == tmp2);
break;
case 4: {
tmp1 = f->getScaleFactor();
tmp2 = atof(val.c_str());
isEqual = (tmp1 == tmp2);
break;
}
case 5: {
float t1 = f->getXCenter();
float t2 = f->getYCenter();
float t3 = f->getAngle();
float t4 = f->getScaleFactor();
tmp2 = atof(val.c_str());
isEqual = (t1 == tmp2 ||
t2 == tmp2 ||
t3 == tmp2 ||
t4 == tmp2);
break;
}
case 6:
if (val.compare("C") == 0){
if (typeid(*f)==typeid(Circle))
isEqual = true;
} else if (val.compare("E") == 0)
if (typeid(*f)==typeid(Elipse))
isEqual = true;
break;
}
if (isEqual){
findedFigures->push_back(f);
}
}
cout << endl;
showAllElements(findedFigures);
delete findedFigures;
}
void Programm::requestsMenu(){
int choise;
char s[10];
do {
cout << endl;
showAllElements();
cout << endl;
cout << "<1>.Добавить елемент" << endl;
cout << "<2>.Изменить елемент" << endl;
cout << "<3>.Удалить елемент" << endl;
cout << "<4>.Работать с елементом" << endl;
cout << "<5>.Выйти в главное меню" << endl;
cin.getline(s,10);
choise=atoi(s);
if (choise == 1){
Figure* f;
cout << "Объект какого типа вы хотите содать?" << endl;
cout<<"<1>.Круг"<<endl;
cout<<"<2>.Эллипс"<<endl;
cin.getline(s,10);
choise=atoi(s);
if (choise == 1)
f = new Circle();
else if (choise == 2)
f = new Elipse();
f->input();
cout << "В какую позицию добавить елемент?" << endl;
cin.getline(s,10);
choise=atoi(s);
deque<Figure*>::iterator it;
if (collection->size() > 0){
if (choise <= 0){
cout << "Выбрано слишком малое значение. Вставка в начало" << endl;
it = collection->begin();
} else if (choise > collection->size()){
if (choise - collection->size() >= 2)
cout << "Выбрано слишком большое значение. Вставка в конец" << endl;
it = collection->end();
} else {
it = collection->begin()+choise-1;
}
collection->insert(it, f);
} else
collection->push_back(f);
choise = -1;
} else if (choise == 2){
cout << "Введите номер елемента: " << endl;
cin.getline(s,10);
choise=atoi(s);
if (choise >= 1 && (choise-1) < collection->size())
collection->at(choise-1)->input();
else
cout << "Елемента с таким номером не существует" << endl;
choise = -1;
} else if (choise == 3){
cout << "Введите номер елемента: " << endl;
cin.getline(s,10);
choise=atoi(s);
if (choise >= 1 && (choise-1) < collection->size())
collection->erase(collection->begin()+choise-1);
else
cout << "Елемента с таким номером не существует" << endl;
choise = -1;
} else if (choise == 4){
cout << "Введите номер елемента: " << endl;
cin.getline(s,10);
choise=atoi(s);
Figure *f;
if (choise >= 1 && (choise-1) < collection->size())
f = collection->at(choise-1);
else {
cout << "Елемента с таким номером не существует" << endl;
break;
}
cout << "Что сделать с фигурой ?" << endl;
cout << "<1>.Переместить на заданый вектор" << endl;
cout << "<2>.Переместить на заданый угол" << endl;
cout << "<3>.Сделать невидимой" << endl;
cout << "<4>.Сделать видимой" << endl;
cin.getline(s,10);
int choise1 = atoi(s);
switch (choise1){
case 1:{
float x;
float y;
cout << "Введите x:" << endl;
cin.getline(s,10); dotsToCommasChar(s, 10);
x = atof(s);
cout << "Введите у:" << endl;
cin.getline(s,10); dotsToCommasChar(s, 10);
y = atof(s);
f->moveBy(x, y);
}
break;
case 2:{
float a;
cout << "Введите угол:" << endl;
cin.getline(s,10); dotsToCommasChar(s, 10);
a = atof(s);
f->rotateBy(a);
}
break;
case 3:
f->hide();
break;
case 4:
f->unHide();
break;
}
}
} while (choise != 5);
}
