Скачиваний:
55
Добавлен:
05.07.2021
Размер:
112.55 Кб
Скачать

3 Индивидуальное задание

Разработать набор классов (минимум 5 классов) по теме использование текстового редактора пользователями с автоматическим сохранением данных в файл. Редактор должен поддерживать возможность отмены внесенных изменений (отменить ввод, Undo, Ctrl+Z) и восстановления отмененной информации (вернуть ввод, Ctrl+Y, Redo). Для хранения историй модификации файла использовать список (его рациональную организацию определить самостоятельно). Разработанный набор классов должен иметь параметры типа. Все классы должны иметь методы получения и изменения своих полей. Использовать smart-указатели для создания программы, которая определяет возможность самостоятельного закрытия файла (т.е. данные файла сохранены и с ним никто сейчас не работает).

4 Код решения индивидуального задания

input.h

#pragma once

#pragma once

#include <iostream>

#include <conio.h>

#include <cstring>

void input(int& number)

{

int index = 0;

char str[4 + 1];

char ch;

bool sign = false;

do {

ch = _getch();

if (index == 0 && ch == '-' && !sign)

{

sign = true;

std::cout << "-";

}

else if (index == 0 && ch == 8 && sign)

{

std::cout << "\b \b";

sign = false;

}

if (ch == '\r' && index == 0)

{

ch = 0;

}

else if (index == 0 && ((ch >= '0' && ch <= '9')) && ch != 8)

{

std::cout << ch;

str[index] = ch;

index++;

}

else if (index > 0)

{

if (ch == 8)

{

index--;

str[index] = '\0';

std::cout << "\b \b";

}

else if (index >= 4)

{

;

}

else if (ch >= '0' && ch <= '9')

{

std::cout << ch;

str[index] = ch;

index++;

}

}

} while (ch != '\r');

str[index] = '\0';

std::cout << std::endl;

number = atoi(str);

if (sign) number *= -1;

}

void inputLat(std::string& str, int length)

{

int index = 0;

char ch;

do

{

ch = _getch();

if (ch == '\r' && index == 0)

{

ch = 0;

}

else if (ch == 8 && index > 0)

{

index--;

str.erase(index);

std::cout << "\b \b";

}

else if (index < 0 || index >= length)

{

;

}

else if ((ch >= '0' && ch <= '9') || ch == ' ' || ch == '№' || ch == '/' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= 'а' && ch <= 'я') || (ch >= 'А' && ch <= 'Я') || (ch == 'ё' || ch == 'Ё'))

{

std::cout << ch;

str.push_back(ch);

index++;

}

} while (ch != '\r');

std::cout << std::endl;

}

input.cpp”

#include <iostream>

#include <fstream>

#include <vector>

#include <iomanip>

#include <Windows.h>

#include "input.h"

using namespace std;

ostream& date(ostream& stream, int year, int day, int month)

{

if (day < 10) cout << "0";

cout << day << ".";

if (month < 10) cout << "0";

cout << month << ".";

cout << year;

return stream;

}

class Employee

{

public:

string name;

string place;

static const string file;

void output()

{

cout << name;

cout << " || " << place << endl;

}

void fwrite(ofstream& file)

{

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == ' ') name.at(i) = '.';

}

for (int i = 0; i < place.size(); i++)

{

if (place.at(i) == ' ') place.at(i) = '.';

}

file << name << endl;

file << place;

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == '.') name.at(i) = ' ';

}

for (int i = 0; i < place.size(); i++)

{

if (place.at(i) == '.') place.at(i) = ' ';

}

}

void fread(ifstream& file)

{

file >> name;

file >> place;

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == '.') name.at(i) = ' ';

}

for (int i = 0; i < place.size(); i++)

{

if (place.at(i) == '.') place.at(i) = ' ';

}

}

};

class Document

{

public:

static const string file;

string name;

string edInstitution;

int year;

int month;

int day;

void fwrite(ofstream& file)

{

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == ' ') name.at(i) = '.';

}

for (int i = 0; i < edInstitution.size(); i++)

{

if (edInstitution.at(i) == ' ') edInstitution.at(i) = '.';

}

file << name << endl;

file << edInstitution << endl;

file << year << endl;

file << month << endl;

file << day;

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == '.') name.at(i) = ' ';

}

for (int i = 0; i < edInstitution.size(); i++)

{

if (edInstitution.at(i) == '.') edInstitution.at(i) = ' ';

}

}

void fread(ifstream& file)

{

file >> name;

file >> edInstitution;

file >> year;

file >> month;

file >> day;

for (int i = 0; i < name.size(); i++)

{

if (name.at(i) == '.') name.at(i) = ' ';

}

for (int i = 0; i < edInstitution.size(); i++)

{

if (edInstitution.at(i) == '.') edInstitution.at(i) = ' ';

}

}

void output()

{

cout << "|| " << setiosflags(ios::left) << setw(25) << name;

cout << " | " << setw(20) << edInstitution;

cout << " | ";

date(cout, year, day, month) << endl;

}

void input()

{

cout << "Название документа : ";

inputLat(name, 25);

cout << "ВУЗ : ";

inputLat(edInstitution, 20);

cout << "Срок сдачи задания студентами" << endl;

cout << "День : ";

::input(day);

cout << "Месяц : ";

::input(month);

cout << "Год : ";

::input(year);

}

void inputTransaction(string edInstitution)

{

this->edInstitution = edInstitution;

cout << "Название документа : ";

inputLat(name, 25);

cout << "Срок сдачи задания студентами" << endl;

cout << "День : ";

::input(day);

cout << "Месяц : ";

::input(month);

cout << "Год : ";

::input(year);

}

void set(Document doc)

{

this->day = doc.day;

this->month = doc.month;

this->year = doc.year;

this->name = doc.name;

this->edInstitution = doc.edInstitution;

}

};

template <class T>

class Transaction

{

public:

T* prevState;

T* currentState;

Transaction(T* doc) {

prevState = NULL;

currentState = new T;

currentState = doc;

}

~Transaction() { delete currentState; delete prevState; }

void show()

{

cout << "состояния объекта" << endl;

if (prevState)

{

cout << "prevState = " << endl;

prevState->output();

cout << endl;

cout << "currentState = " << endl;

currentState->output();

cout << endl;

}

else

{

cout << "prevState = NULL" << endl;

cout << "currentState = " << endl;

currentState->output();

cout << endl;

}

}

bool BeginTransactions(T* newState)

{

delete prevState;

prevState = currentState;

currentState = new T(*prevState);

if (!currentState) return 0;

currentState->set(*newState);

return 1;

}

void commit()

{

prevState = NULL;

}

void DeleteTransactions()

{

if (prevState != NULL) {

currentState = NULL;

delete currentState;

currentState = prevState;

prevState = NULL;

}

}

T* operator->() { return currentState; };

};

template <class T>

struct Status {

T* ptr;

int counter;

};

template <typename T>

class SmartPointer {

Status<T>* smartPtr;

public:

static const string file;

SmartPointer(T* ptr = 0);

int showCounter() { return smartPtr->counter; }

~SmartPointer() {

if (smartPtr) {

smartPtr->counter--;

if (smartPtr->counter <= 0) {

delete smartPtr->ptr;

delete smartPtr;

}

}

}

T* operator->() const

{

if (smartPtr) return smartPtr->ptr;

else return NULL;

}

T& getPtr() const { return *smartPtr->ptr; }

SmartPointer(const SmartPointer& obj) :smartPtr(obj.smartPtr) {

if (smartPtr) smartPtr->counter++;

}

};

template <class T>

SmartPointer<T>::SmartPointer(T* ptr) {

smartPtr = new Status<T>;

smartPtr->ptr = ptr;

smartPtr->counter = 1;

}

template <class T>

class File

{

public:

static void fread(vector<SmartPointer<T>>& vect)

{

ifstream file(T::file);

while (!file.eof())

{

SmartPointer<T> newItem(new T);

newItem->fread(file);

vect.push_back(newItem);

}

file.close();

}

static void fwrite(vector<SmartPointer<T>> vect)

{

ofstream file(T::file);

for (int i = 0; i < vect.size(); i++)

{

vect.at(i)->fwrite(file);

if (i != vect.size() - 1) file << endl;

}

file.close();

}

};

const string Employee::file = "employee.txt";

const string Document::file = "document.txt";

template <class T>

void transactMenu(SmartPointer<T>& doc)

{

Transaction<T> transaction(&doc.getPtr());

SmartPointer<T> newDoc(new T);

while (true)

{

system("cls");

cout << "1)Начать транзакцию" << endl;

cout << "2)Откатить состаяние" << endl;

cout << "3)Просмотреть состояние транзакции" << endl;

cout << "4)Сохранить изменения и выйти" << endl;

cout << ">> ";

int choice;

::input(choice);

switch (choice)

{

case 1:

{

newDoc->inputTransaction(transaction.currentState->edInstitution);

transaction.BeginTransactions(&newDoc.getPtr());

break;

}

case 2:

{

transaction.DeleteTransactions();

break;

}

case 3:

{

system("cls");

transaction.show();

system("pause");

break;

}

case 4:

{

doc.getPtr() = *transaction.currentState;

transaction.commit();

system("cls");

transaction.show();

transaction = NULL;

system("pause");

return;

}

default: cout << "Неверный ввод" << endl; system("pause"); break;

}

}

}

void menu(SmartPointer<Employee> me)

{

vector<SmartPointer<Document>> vect;

File<Document>::fread(vect);

while (true)

{

system("cls");

cout << "1)Просмотр загруженных документов" << endl;

cout << "2)Меню транзакции" << endl;

cout << "3)Добавить документ с домашним заданием" << endl;

cout << "4)Удалить документ с домашним заданием" << endl;

cout << "5)Назад" << endl;

cout << ">> ";

int choice;

::input(choice);

switch (choice)

{

case 1:

{

if (!vect.size()) { cout << "Список пуст" << endl; system("pause"); break; }

system("cls");

cout << " " << setw(25) << " Название";

cout << " " << " ВУЗ";

cout << " " << " Срок сдачи задания студентами" << endl;

bool checking = false;

for (int i = 0; i < vect.size(); i++)

{

if (me->place == vect.at(i)->edInstitution)

{

vect.at(i)->output();

checking = true;

}

}

if (!checking) {

cout << "Нет доступных документов" << endl;

}

system("pause");

break;

}

case 2:

{

if (!vect.size()) { cout << "Список пуст" << endl; system("pause"); break; }

system("cls");

cout << " " << setw(25) << " Название";

cout << " " << " ВУЗ";

cout << " " << "Срок сдачи задания студентами" << endl;

bool checking = false;

for (int i = 0; i < vect.size(); i++)

{

if (me->place == vect.at(i)->edInstitution)

{

vect.at(i)->output();

checking = true;

}

}

if (!checking) {

cout << "Нет доступных документов" << endl;

break;

}

system("pause");

string name;

cout << "Название документа : ";

inputLat(name, 25);

for (int i = 0; i < vect.size(); i++)

{

if (vect.at(i)->name == name)

{

transactMenu<Document>(vect.at(i));

File<Document>::fwrite(vect);

break;

}

}

break;

}

case 3:

{

system("cls");

SmartPointer<Document> newDoc(new Document);

newDoc->input();

vect.push_back(newDoc);

File<Document>::fwrite(vect);

break;

}

case 4:

{

if (!vect.size()) { cout << "Список пуст" << endl; system("pause"); break; }

system("cls");

cout << " " << setw(25) << " Название";

cout << " " << " ВУЗ";

cout << " " << "Срок сдачи задания студентами" << endl;

bool checking = false;

for (int i = 0; i < vect.size(); i++)

{

if (me->place == vect.at(i)->edInstitution)

{

vect.at(i)->output();

checking = true;

}

}

if (!checking) {

cout << "Нет доступных документов" << endl;

break;

}

system("pause");

string name;

cout << "Название документа : ";

inputLat(name, 25);

for (int i = 0; i < vect.size(); i++)

{

if (vect.at(i)->name == name)

{

vect.erase(i + vect.begin());

File<Document>::fwrite(vect); break;

}

}

cout << "Документ не найден" << endl;

system("pause");

break;

}

case 5: return;

default: cout << "Неверный ввод" << endl; system("pause"); break;

}

}

}

int main()

{

SetConsoleCP(1251);

SetConsoleOutputCP(1251);

vector<SmartPointer<Employee>> empl;

File<Employee>::fread(empl);

while (true)

{

system("cls");

cout << "1)Вход" << endl;

cout << "2)Добавить преподавателя" << endl;

cout << "3)Просмотр списка преподавателей университета" << endl;

cout << "4)Выход" << endl;

cout << ">> ";

int choice;

::input(choice);

switch (choice)

{

case 1:

{

if (!empl.size())

{

cout << "Список пуст" << endl;

system("pause");

break;

}

system("cls");

string name;

cout << "Фамилия преподавателя : ";

inputLat(name, 25);

bool checking = false;

;

for (int i = 0; i < empl.size(); i++)

{

if (empl.at(i)->name == name)

{

menu(empl.at(i));

checking = true;

break;

}

}

if (!checking) cout << "Преподаватель не найден" << endl;

system("pause");

break;

}

case 2:

{

system("cls");

SmartPointer<Employee> newEm(new Employee);

cout << "Фамилия преподавателя : ";

inputLat(newEm->name, 25);

cout << "Университет : ";

inputLat(newEm->place, 30);

empl.push_back(newEm);

system("pause");

File<Employee>::fwrite(empl);

break;

}

case 3:

{

if (!empl.size())

{

cout << "Список пуст" << endl;

system("pause");

break;

}

system("cls");

for (int i = 0; i < empl.size(); i++)

{

cout << setiosflags(ios::left) << i + 1 << ". ";

empl.at(i)->output();

}

system("pause");

break;

}

case 4: return 0;

default: cout << "Неверный ввод" << endl; system("pause"); break;

}

}

}

Соседние файлы в папке лабы Салапура 2ая часть (4 семестр)