ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 04.12.2023
Просмотров: 37
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
ФЕДЕРАЛЬНОЕ ГОСУДАРСТЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ОБРАЗОВАНИЯ
«БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ
УНИВЕРСИТЕТ им. В.Г. ШУХОВА»
(БГТУ им. В.Г. Шухова)
Кафедра программного обеспечения вычислительной техники и автоматизированных систем
по дисциплине: Объектно-ориентированное программирование
тема: «Программа для ведения Блога»
Выполнил:
Проверил:
Буханов Д. Г.
Белгород
2020
Введение
Цель работы: разработать программу, с помощью которой можно создавать и вести блог.
Полное задание: каждый блог принадлежит одному пользователю и состоит из нескольких записей. В момент создания блога в нем записей нет. Пользователь может создавать записи лишь в собственном блоге. Читать записи любого пользователя может каждый пользователь. В каждой записи есть заголовок, дата, текст. На каждой странице блога находятся ссылка на профиль. На начальной странице блога отображаются 10 последних записей (или менее, если в блоге их недостаточно). Если записей в блоге больше 10, то с начальной страницы можно перейти на вторую, где отображается второй десяток записей и т. д. Записи в блоге упорядочены по убыванию даты. Любая запись может быть отредактирована, но дата записи не может быть изменена. Запись может быть удалена автором. Перейдя на страницу отдельной записи, пользователь может ее комментировать, независимо от того, чужая это запись или его собственная. Комментарий состоит из текста и даты, указывающей, когда он написан. Комментарий может быть дан к записи блога или к ранее написанному комментарию. Пользователь может запретить комментирование любой записи в своем блоге. Комментарии, полученные раньше запрета, сохраняются. Запрет на комментирование может быть снят. Все комментарии к записи отображаются под ее текстом в виде дерева. Каждый комментарий помечен именем его автора. Имя может быть использовано для перехода к начальной странице блога с этим именем. Комментарии не могут быть отредактированы, но могут быть удалены автором записи. При удалении комментария также стираются все ответы на него, если таковые были. Любой желающий вести блог должен зарегистрироваться. При регистрации пользователь заполняет форму, указывая желаемое имя, пароль, список своих интересов, дату рождения, контакты, краткие сведения о себе. Если имя не занято, и форма заполнена полностью, система заводит блог нового пользователя. Сведения из регистрационной формы (кроме пароля) отображаются на странице профиля пользователя. Пользователь может отредактировать собственный профиль, изменив в нем все, кроме имени. Пользователь может изменить свой пароль. Пароль не может быть короче 8 символов. Зарегистрированный пользователь, осуществляет вход в собственный блог, указывая имя и пароль. Все описанные выше действия с записями, комментариями и собственным профилем, действия с друзьями доступны пользователю только после входа. Пользователь может полностью удалить свой блог со всеми записями, комментариями и профилем. После удаления блога регистрационные данные стираются из системы.
Основная часть
Объектная декомпозиция
Простейшая объектная декомпозиция.
Диаграмма классов
Пример интерпретации базы данных
Хранить будем регистрационные данные отдельно, список друзей отдельно, список записей в блоге юзера отдельно.
Файл с регистрационными данными:
Файл со списком друзей
Первая строка – пользователь, остальные его друзья.
Файл со списком записей
Код программы
Файл “User_Post.h”.
Данный файл хранит абстрактный класс Post, двух его наследников Publicaion и Comment, а также класс User.
#include
#include
#include
class Post
{
protected:
std::string header;
std::string text;
std::string date;
public:
Post(std::string head, std::string txt, std::string tm) : header(head), text(txt), date(tm){}
Post(){}
virtual void show()
{
std::cout << "\t"+header << "\t"+date << std::endl << "\t"+text << std::endl;
}
virtual std::string getText() { return text; }
virtual std::string getDate() { return date; }
virtual std::string getHeader() { return header; }
};
class Publication : public Post
{
std::vector comments;
public:
Publication(std::string head, std::string txt, std::string tm) : Post(head, txt, tm) {}
void addComment(Post* com)
{
comments.push_back(com);
}
void setComments(std::vector coms)
{
comments = coms;
}
std::string getHeader()
{
return header;
}
std::string getText()
{
return text;
}
std::string getDate()
{
return date;
}
std::vector getComments()
{
return comments;
}
void setHeader(std::string head)
{
header = head;
}
void setText(std::string txt)
{
text = txt;
}
void setDate(std::string dt)
{
date = dt;
}
void show()
{
std::cout << "--------------------------------------" << std::endl;
std::cout << "\t"+header << std::endl;
std::cout << "--------------------------------------" << std::endl;
std::cout << text << std::endl << date << std::endl;
std::cout << "--------------------------------------" << std::endl;
}
};
class User
{
std::string username;
std::string password;
std::string hobbies;
std::string contacts;
std::string short_self_info;
std::string birthdate;
bool commenting_permission = true;
std::vector friends;
std::vector posts;
public:
User(std::string login, std::string pass, std::string cont, std::string hob, std::string s_i, std::string birth, bool com_per) : username(login), password(pass), hobbies(hob), contacts(cont), short_self_info(s_i), birthdate(birth), commenting_permission(com_per) {}
User(std::string login, std::string pass, std::string cont, std::string hob, std::string s_i, std::string birth) : username(login), password(pass), hobbies(hob), contacts(cont), short_self_info(s_i), birthdate(birth) {}
User(){}
ФЕДЕРАЛЬНОЕ ГОСУДАРСТЕННОЕ БЮДЖЕТНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ОБРАЗОВАНИЯ
«БЕЛГОРОДСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНОЛОГИЧЕСКИЙ
УНИВЕРСИТЕТ им. В.Г. ШУХОВА»
(БГТУ им. В.Г. Шухова)
Кафедра программного обеспечения вычислительной техники и автоматизированных систем
по дисциплине: Объектно-ориентированное программирование
тема: «Программа для ведения Блога»
Выполнил:
Проверил:
Буханов Д. Г.
Белгород
2020
Введение
Цель работы: разработать программу, с помощью которой можно создавать и вести блог.
Полное задание: каждый блог принадлежит одному пользователю и состоит из нескольких записей. В момент создания блога в нем записей нет. Пользователь может создавать записи лишь в собственном блоге. Читать записи любого пользователя может каждый пользователь. В каждой записи есть заголовок, дата, текст. На каждой странице блога находятся ссылка на профиль. На начальной странице блога отображаются 10 последних записей (или менее, если в блоге их недостаточно). Если записей в блоге больше 10, то с начальной страницы можно перейти на вторую, где отображается второй десяток записей и т. д. Записи в блоге упорядочены по убыванию даты. Любая запись может быть отредактирована, но дата записи не может быть изменена. Запись может быть удалена автором. Перейдя на страницу отдельной записи, пользователь может ее комментировать, независимо от того, чужая это запись или его собственная. Комментарий состоит из текста и даты, указывающей, когда он написан. Комментарий может быть дан к записи блога или к ранее написанному комментарию. Пользователь может запретить комментирование любой записи в своем блоге. Комментарии, полученные раньше запрета, сохраняются. Запрет на комментирование может быть снят. Все комментарии к записи отображаются под ее текстом в виде дерева. Каждый комментарий помечен именем его автора. Имя может быть использовано для перехода к начальной странице блога с этим именем. Комментарии не могут быть отредактированы, но могут быть удалены автором записи. При удалении комментария также стираются все ответы на него, если таковые были. Любой желающий вести блог должен зарегистрироваться. При регистрации пользователь заполняет форму, указывая желаемое имя, пароль, список своих интересов, дату рождения, контакты, краткие сведения о себе. Если имя не занято, и форма заполнена полностью, система заводит блог нового пользователя. Сведения из регистрационной формы (кроме пароля) отображаются на странице профиля пользователя. Пользователь может отредактировать собственный профиль, изменив в нем все, кроме имени. Пользователь может изменить свой пароль. Пароль не может быть короче 8 символов. Зарегистрированный пользователь, осуществляет вход в собственный блог, указывая имя и пароль. Все описанные выше действия с записями, комментариями и собственным профилем, действия с друзьями доступны пользователю только после входа. Пользователь может полностью удалить свой блог со всеми записями, комментариями и профилем. После удаления блога регистрационные данные стираются из системы.
Основная часть
Объектная декомпозиция
Простейшая объектная декомпозиция.
Диаграмма классов
Пример интерпретации базы данных
Хранить будем регистрационные данные отдельно, список друзей отдельно, список записей в блоге юзера отдельно.
Файл с регистрационными данными:
Файл со списком друзей
Первая строка – пользователь, остальные его друзья.
Файл со списком записей
Код программы
Файл “User_Post.h”.
Данный файл хранит абстрактный класс Post, двух его наследников Publicaion и Comment, а также класс User.
#include
#include
#include
class Post
{
protected:
std::string header;
std::string text;
std::string date;
public:
Post(std::string head, std::string txt, std::string tm) : header(head), text(txt), date(tm){}
public:
Publication(std::string head, std::string txt, std::string tm) : Post(head, txt, tm) {}
void addComment(Post* com)
{
comments.push_back(com);
}
void setComments(std::vector
{
comments = coms;
}
std::string getHeader()
{
return header;
}
std::string getText()
{
return text;
}
std::string getDate()
{
return date;
}
std::vector
{
return comments;
}
void setHeader(std::string head)
{
header = head;
}
void setText(std::string txt)
{
text = txt;
}
void setDate(std::string dt)
{
date = dt;
}
void show()
{
std::cout << "--------------------------------------" << std::endl;
std::cout << "\t"+header << std::endl;
std::cout << "--------------------------------------" << std::endl;
std::cout << text << std::endl << date << std::endl;
std::cout << "--------------------------------------" << std::endl;
}
};
class User
{
std::string username;
std::string password;
std::string hobbies;
std::string contacts;
std::string short_self_info;
std::string birthdate;
bool commenting_permission = true;
std::vector
std::vector
public:
User(std::string login, std::string pass, std::string cont, std::string hob, std::string s_i, std::string birth, bool com_per) : username(login), password(pass), hobbies(hob), contacts(cont), short_self_info(s_i), birthdate(birth), commenting_permission(com_per) {}
User(std::string login, std::string pass, std::string cont, std::string hob, std::string s_i, std::string birth) : username(login), password(pass), hobbies(hob), contacts(cont), short_self_info(s_i), birthdate(birth) {}
void addPost(Publication* post)
{
posts.push_back(post);
}
void addFriend(User * pal)
{
friends.push_back(pal);
}
void setNewPassword(std::string pass)
{
password = pass;
}
void setNewHobbies(std::string hob)
{
hobbies = hob;
}
void setNewContacts(std::string cont)
{
contacts = cont;
}
void setNewSelfInfo(std::string s_s_i)
{
short_self_info = s_s_i;
}
void setNewBirthdate(std::string birth)
{
birthdate = birth;
}
void setFriends(std::vector
{
friends = pals;
}
void setPosts(std::vector
{
posts = p;
}
void showProfile()
{
std::cout << "------------------------------------------" << std::endl;
std::cout << "| " << username;
std::cout << "\t Birthdate: " << birthdate << std::endl;
std::cout << "------------------------------------------" << std::endl;
std::cout << "Info: " << short_self_info << std::endl;
std::cout << "Hobbies: " << hobbies << std::endl;
std::cout << "Contacts: " << contacts << std::endl;
}
std::string getLogin()
{
return username;
}
std::string getPass()
{
return password;
}
std::string getHobbies()
{
return hobbies;
}
std::string getContacts()
{
return contacts;
}
std::string getSelfInfo()
{
return short_self_info;
}
std::string getBirthdate()
{
return birthdate;
}
bool getComPer()
{
return commenting_permission;
}
std::vector
{
return friends;
}
std::vector
{
return posts;
}
void changeComPer()
{
commenting_permission = !commenting_permission;
}
void disableCommenting()
{
commenting_permission = false;
}
void allowCommenting()
{
commenting_permission = true;
}
};
class Comment : public Post
{
User * author;
public:
Comment(std::string txt, std::string tm, User* u) : Post(u->getLogin(), txt, tm), author(u) {}
std::string getText()
{
return text;
}
std::string getDate()
{
return date;
}
std::string getHeader()
{
return header;
}
void show()
{
std::cout << "\t"+header << "\t"+date << std::endl << "\t>> "+text << std::endl;
}
};
Файл “Menu.h”.
Данный файл хранит множество меню, которые вызывают друг друга в зависимости от выбора юзера.
#include "BDWorker.h"
class Menu
{
protected:
std::vector<:string> menu_items;
public:
void show()
{
std::cout << "\tMenu" << std::endl;
for (auto item : menu_items) std::cout << item << std::endl;
}
virtual Menu* open(User* u, User* guest){return new Menu();}
};
class StartMenu : public Menu
{
public:
StartMenu(User* u, User* guest){menu_items.push_back("1) Sign in"); menu_items.push_back("2) Sign up"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class LoginMenu : public Menu
{
public:
LoginMenu(User* u, User* guest){menu_items.push_back("1) Login"); menu_items.push_back("2) Step back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class RegistrationMenu : public Menu
{
public:
RegistrationMenu(User* u, User* guest){menu_items.push_back("1) Create accout"); menu_items.push_back("2) Step back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class MyProfileMenu : public Menu
{
public:
MyProfileMenu(User* u, User* guest){menu_items.push_back("1) Open Post Menu"); menu_items.push_back("2) Open Friend's List"); menu_items.push_back("3) Go to Settings"); menu_items.push_back("4) Exit"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class MyFriendList : public Menu
{
public:
MyFriendList(User* u, User* guest){menu_items.push_back("1) Visit Friend"); menu_items.push_back("2) Add Friend"); menu_items.push_back("3) Delete Friend"); menu_items.push_back("4) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class FriendList : public Menu
{
public:
FriendList(User* u, User* guest){menu_items.push_back("1) Visit Friend"); menu_items.push_back("2) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class SettingsMenu : public Menu
{
public:
SettingsMenu(User* u, User* guest){menu_items.push_back("1) Change password"); menu_items.push_back("2) Change Self Info"); menu_items.push_back("3) Change hobbies"); menu_items.push_back("4) Change Contacts "); menu_items.push_back("5) Change Commenting Permissions: " + std::to_string(u->getComPer())); menu_items.push_back("6) Delete Account"); menu_items.push_back("7) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class ExitMenu : public Menu
{
public:
ExitMenu(User* u, User* guest){open(u, guest);}
Menu* open(User* u, User* guest);
};
class MyPostsMenu : public Menu
{
public:
MyPostsMenu(User* u, User* guest){menu_items.push_back("1) Create Post"); menu_items.push_back("2) Watch Posts"); menu_items.push_back("3) Edit Post"); menu_items.push_back("4) Delete Post"); menu_items.push_back("5) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class MyPostPaginator : public Menu
{
public:
MyPostPaginator(User* u, User* guest){open(u, guest);}
Menu* open(User* u, User* guest);
};
class PostPaginator : public Menu
{
public:
PostPaginator(User* u, User* guest){open(u, guest);}
Menu* open(User* u, User* guest);
};
class CreatePostsMenu : public Menu
{
public:
CreatePostsMenu(User* u, User* guest){menu_items.push_back("1) Create"); menu_items.push_back("2) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class DeletePostMenu : public Menu
{
public:
DeletePostMenu(User* u, User* guest){menu_items.push_back("1) Choose"); menu_items.push_back("2) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class EditPostMenu : public Menu
{
public:
EditPostMenu(User* u, User* guest){menu_items.push_back("1) Change Header"); menu_items.push_back("2) Change Text"); menu_items.push_back("3) Step Back"); open(u, guest);}
Menu* open(User* u, User* guest);
};
class ProfileMenu : public Menu
{
public:
ProfileMenu(User* u, User* guest){menu_items.push_back("1) Show Posts"); menu_items.push_back("2) Open Friend List"); menu_items.push_back("3) Go to my profile"); open(u, guest);}
Menu* open(User* u, User* guest);
};
Файл «Menu.cpp»
Описания метода «open()», открывающего следующее меню, в различных меню.
#include "Menu.h"
UsersDataBase* UsersDataBase::p_instance = 0;
int getAnswer(std::vector<:string> items)
{
int answ;
do {
std::cout << "\nEnter item: ";
std::cin >> answ;
} while ((answ > items.size()) || (answ < 1));
return answ;
}
void deleteUser(User* u)
{
BDWorker users;
Poster p(u);
p.deleteMe(u);
Friender f(u);
f.deleteMe(u);
users.deleteMe(u);
}
std::string getTodayDate()
{
std::time_t t = std::time(nullptr);
char buf[64];
strftime(buf, sizeof(buf), "%d.%m.%Y", localtime(&t));
return buf;
}
Menu* StartMenu::open(User* u, User* guest)
{
system("cls");
show();
switch (getAnswer(menu_items))
{
case 1:
return new LoginMenu(u, guest);
break;
case 2:
return new RegistrationMenu(u, guest);
break;
default:
break;
}
return new StartMenu(u, guest);
}
Menu* LoginMenu::open(User* u, User* guest)
{
system("cls");
std::string login;
std::string pass;
std::cout << "Login: ";
std::cin >> login;
std::cout << "Password: ";
std::cin >> pass;
BDWorker users;
u = users.find(login, pass);
show();
switch (getAnswer(menu_items))
{
case 1:
if (u == nullptr)
{
std::cout << "Wrong login or password!!!" << std::endl;
system("pause");
}
else
return new MyProfileMenu(u, guest);
break;
case 2:
return new StartMenu(u, guest);
break;
default:
break;
}
return new LoginMenu(u, guest);
}
Menu* RegistrationMenu::open(User* u, User* guest)
{
system("cls");
std::string login;
std::string pass;
std::cout << "Login: ";
std::cin >> login;
std::cout << "Password: ";
std::cin >> pass;
BDWorker users;
u = users.find(login, pass);
if (u != nullptr)
{
std::cout << "A user with the same name already exists...";
system("pause");
return new RegistrationMenu(u, guest);
}
if (pass.size() < 8)
{
std::cout << "A user with the same name already exists...";
system("pause");
return new RegistrationMenu(u, guest);
}
std::string short_info;
std::cout << "Short info: ";
_flushall();
std::getline(std::cin, short_info);
std::string birthdate;
std::cout << "Birthdate (dd.mm.yy): ";
_flushall();
std::getline(std::cin, birthdate);
std::string hobbies;
std::cout << "Hobbies: ";
_flushall();
std::getline(std::cin, hobbies);
std::string contacts;
std::cout << "Contacts: ";
_flushall();
std::getline(std::cin, hobbies);
show();
switch (getAnswer(menu_items))
{
case 1:
users.add(new User(login, pass, contacts, hobbies, short_info, birthdate));
return new LoginMenu(u, guest);
break;
case 2:
return new StartMenu(u, guest);
break;
default:
break;
}
return new RegistrationMenu(u, guest);
}
Menu* MyProfileMenu::open(User* u, User* guest)
{
system("cls");
u->showProfile();
show();
switch (getAnswer(menu_items))
{
case 1:
return new MyPostsMenu(u, guest);
break;
case 2:
return new MyFriendList(u, guest);
break;
case 3:
return new SettingsMenu(u, guest);
break;
case 4:
return new ExitMenu(u, guest);
break;
default:
break;
}
return new ProfileMenu(u, guest);
}
Menu* MyPostsMenu::open(User* u, User* guest)
{
system("cls");
u->showProfile();
show();
switch (getAnswer(menu_items))
{
case 1:
return new CreatePostsMenu(u, guest);
break;
case 2:
return new MyPostPaginator(u, nullptr);
break;
case 3:
return new EditPostMenu(u, guest);
break;
case 4:
return new DeletePostMenu(u, guest);
break;
case 5:
return new MyProfileMenu(u, guest);
break;
default:
break;
}
return new MyPostsMenu(u, guest);
}
Menu* CreatePostsMenu::open(User* u, User* guest)
{
system("cls");
Poster p(u);
std::string header;
std::string txt;
std::string date;
u->showProfile();
show();
switch (getAnswer(menu_items))
{
case 1:
// Создаем пост, добавляем его в вектор юзера
std::cout << "Enter header: ";
_flushall();
std::getline(std::cin, header);
std::cout << "Enter text:" << std::endl;
_flushall();
std::getline(std::cin, txt);
date = getTodayDate();
u->addPost(new Publication(header, txt, date));
p.update(u->getLogin(), u->getPosts());
std::cout << u->getPosts().size() << std::endl;
return new MyPostsMenu(u, guest);
break;
case 2:
return new MyPostsMenu(u, guest);
break;
default:
break;
}
return new CreatePostsMenu(u, guest);
}
Menu* DeletePostMenu::open(User* u, User* guest)
{
system("cls");
Poster p(u);
std::vector
std::string headline;
u->showProfile();
show();
switch (getAnswer(menu_items))
{
case 1:
std::cout << "Enter header: ";
_flushall();
std::getline(std::cin, headline);
all_posts = u->getPosts();
for (int i = 0; i < all_posts.size(); i++)
{
if (headline == all_posts[i]->getHeader())
{
all_posts.erase(all_posts.begin() + i);
u->setPosts(all_posts);
p.update(u->getLogin(), u->getPosts());
return new MyPostsMenu(u, guest);
}
}
std::cout << "Post not found..." << std::endl;
system("pause");
return new MyPostsMenu(u, guest);
break;
case 2:
return new MyPostsMenu(u, guest);
break;
default:
break;
}
return new DeletePostMenu(u, guest);
}
Menu* EditPostMenu::open(User* u, User* guest)
{
system("cls");
u->showProfile();
std::string new_item;
Poster p(u);
std::vector
std::string headline;
std::cout << "Enter header: ";
_flushall();
std::getline(std::cin, headline);
all_posts = u->getPosts();
for (int i = 0; i < all_posts.size(); i++)
{
if (headline == all_posts[i]->getHeader())
{
show();
switch (getAnswer(menu_items))
{
case 1:
std::cout << "New Header: ";
_flushall();
std::getline(std::cin, new_item);
all_posts[i]->setHeader(new_item);
break;
case 2:
std::cout << "New Text:" << std::endl ;
_flushall();
std::getline(std::cin, new_item);
all_posts[i]->setText(new_item);
break;
case 3:
return new MyPostsMenu(u, guest);
break;
default:
break;
}
u->setPosts(all_posts);
p.update(u->getLogin(), u->getPosts());
return new MyPostsMenu(u, guest);
}
}
std::cout << "Post not found..." << std::endl;
system("pause");
return new MyPostsMenu(u, guest);
}
Menu* SettingsMenu::open(User* u, User* guest)
{
system("cls");
BDWorker users;
users.update();
u->showProfile();
show();
std::string new_item;
switch (getAnswer(menu_items))
{
case 1:
do{
std::cin >> new_item;
} while (new_item.size() < 8);
u->setNewPassword(new_item);
return new SettingsMenu(u, guest);
break;
case 2:
_flushall();
std::getline(std::cin, new_item);
u->setNewSelfInfo(new_item);
return new SettingsMenu(u, guest);
break;
case 3:
_flushall();
std::getline(std::cin, new_item);
u->setNewHobbies(new_item);
return new SettingsMenu(u, guest);
break;
case 4:
_flushall();
std::getline(std::cin, new_item);
u->setNewContacts(new_item);
return new SettingsMenu(u, guest);
break;
case 5:
u->changeComPer();
return new SettingsMenu(u, guest);
break;
case 6:
deleteUser(u);
return new ExitMenu(u, guest);
break;
case 7:
return new MyProfileMenu(u, guest);
break;
default:
break;
}
return new SettingsMenu(u, guest);
}
Menu* MyFriendList::open(User* u, User* guest)
{
system("cls");
u->showProfile();
Friender pals_adder(u);
std::vector
for (int i = 0; i < pals.size(); i++)
{
std::cout << i+1 << ")" << pals[i]->getLogin() << std::endl;
}
int pal_num;
std::string login;
show();
switch (getAnswer(menu_items))
{
case 1:
do
{
std::cout << "Enter friend number: ";
std::cin >> pal_num;
} while ((pal_num > u->getFriends().size()) || (pal_num < 1));
return new ProfileMenu(u, pals[pal_num-1]);
break;
case 2:
std::cout << "Enter login: ";
std::cin >> login;
pals_adder.findAndAddFriend(u, login);
return new MyFriendList(u, guest);
break;
case 3:
do
{
std::cout << "Enter friend number: ";
std::cin >> pal_num;
} while ((pal_num > u->getFriends().size()) || (pal_num < 1));
pals_adder.findAndDelFriend(u, pal_num-1);
return new MyFriendList(u, guest);
break;
case 4:
return new MyProfileMenu(u, guest);
break;
default:
break;
}
return new FriendList(u, guest);
}
Menu* FriendList::open(User* u, User* guest)
{
system("cls");
guest->showProfile();
Friender pals_adder(guest);
std::vector
for (int i = 0; i < pals.size(); i++)
{
std::cout << i+1 << ")" << pals[i]->getLogin() << std::endl;
}
int pal_num;
show();
switch (getAnswer(menu_items))
{
case 1:
do
{
std::cout << "Enter friend number: ";
std::cin >> pal_num;
} while ((pal_num > u->getFriends().size()) || (pal_num < 1));
return new ProfileMenu(u, pals[pal_num-1]);
break;
case 2:
return new ProfileMenu(u, guest);
break;
default:
break;
}
return new FriendList(u, guest);
}
Menu* ProfileMenu::open(User* u, User* guest)
{
system("cls");
guest->showProfile();
show();
switch (getAnswer(menu_items))
{
case 1:
return new PostPaginator(u, guest);
break;
case 2:
return new FriendList(u, guest);
break;
case 3:
return new MyProfileMenu(u, nullptr);
break;
default:
break;
}
return new ProfileMenu(u, guest);
}
Menu* MyPostPaginator::open(User* u, User* guest)
{
Poster uncle_P(u);
if (u->getPosts().size() == 0)
{
std::cout << "User don't have any posts..." << std::endl;
system("pause");
return new MyPostsMenu(u, nullptr);
}
Paginator petya(u->getPosts());
petya.watchPages(u);
uncle_P.update(u->getLogin(), u->getPosts());
return new MyPostsMenu(u, nullptr);
}
Menu* PostPaginator::open(User* u, User* guest)
{
Poster uncle_P(guest);
if (guest->getPosts().size() == 0)
{
std::cout << "User don't have any posts..." << std::endl;
system("pause");
return new ProfileMenu(u, guest);
}
Paginator valera(guest->getPosts());
valera.watchPages(guest);
uncle_P.update(guest->getLogin(), guest->getPosts());
return new ProfileMenu(u, guest);
}
Menu* ExitMenu::open(User* u, User* guest)
{
system("cls");
u = nullptr;
guest = nullptr;
return new StartMenu(u, guest);
}
Файл “BDWorker.h”.
Данное меню хранит классы, взаимодействующие с реализованной простейшей «базой данных». Для реализации базы регистрационных данных юзеров применим паттерн «Singleton». Благодаря нему мы в любом месте программы сможем получить быстрый доступ к импровизированной базе данных.
#include
1 2
#include
#include
#include
#include "Paginator.h"
class UsersDataBase
{
private:
const std::string first_line_in_file = "login+password+hobbies+self-info+contacts+data+com_per";
std::string filepath;
std::vector users;
static UsersDataBase * p_instance;
UsersDataBase();
UsersDataBase(const UsersDataBase&);
UsersDataBase(std::string path) : filepath(path) {readUsersFullInfo();}
UsersDataBase& operator=(UsersDataBase&);
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
void readUsersFullInfo()
{
std::ifstream file(filepath);
if (file.is_open())
{
std::string line;
std::vector<:string> full_info;
std::getline(file, line);
while (std::getline(file, line))
{
full_info = split(line, '+');
users.push_back(new User(full_info[0], full_info[1], full_info[2], full_info[3], full_info[4], full_info[5], std::stoi(full_info[6])));
}
}
else
std::cout << "File missing!!!" << std::endl;
}
public:
static UsersDataBase * getUsersData(std::string path)
{
if(!p_instance)
p_instance = new UsersDataBase(path);
return p_instance;
}
std::string getPath()
{
return filepath;
}
User* find(std::string login, std::string pass)
{
for (int i = 0; i < users.size(); i++)
{
if ((users[i]->getLogin() == login) && (users[i]->getPass() == pass))
return users[i];
}
return nullptr;
}
void add(User* new_user)
{
std::ofstream file("log_pass.txt", std::ios_base::app);
if (file.is_open())
{
std::string line;
line = line + new_user->getLogin() + "+" + new_user->getPass() + "+" + new_user->getSelfInfo() + "+" + new_user->getContacts() + "+" + new_user->getHobbies() + "+" + new_user->getBirthdate() + "+" + std::to_string(new_user->getComPer());
file << line << std::endl;
}
else
{
std::cout << "File is Missing...";
system("pause");
}
users.push_back(new_user);
}
void update()
{
std::ofstream file("log_pass.txt");
file << first_line_in_file << std::endl;
std::string line;
for (auto u : users)
{
line = line + u->getLogin() + "+" + u->getPass() + "+" + u->getSelfInfo() + "+" + u->getContacts() + "+" + u->getHobbies() + "+" + u->getBirthdate() + "+" + std::to_string(u->getComPer());
file << line << std::endl;
line.clear();
}
}
User* findUserInFriendFiles(std::string login)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == login)
{
return users[i];
}
}
return nullptr;
}
void deleteMe(User* me)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == me->getLogin())
{
users.erase(users.begin() + i);
update();
return;
}
}
}
};
class BDWorker
{
UsersDataBase* bd_users;
public:
BDWorker(){bd_users = UsersDataBase::getUsersData("log_pass.txt");}
BDWorker(){}
User* find(std::string login, std::string pass)
{
return (bd_users->find(login, pass));
}
void add(User* new_user)
{
bd_users->add(new_user);
}
void update()
{
bd_users->update();
}
User* getUserbyLogin(std::string login)
{
return bd_users->findUserInFriendFiles(login);
}
void deleteMe(User* me)
{
bd_users->deleteMe(me);
}
};
class Friender
{
public:
Friender(User * user){user->setFriends(getFriendsFromFile(user->getLogin()));}
Friender(){}
std::vector getFriendsFromFile(std::string username)
{
std::vector pals;
std::ifstream file("friends\\F"+username+".txt");
if (file.is_open())
{
BDWorker users;
std::string line;
std::getline(file, line);
User* buf;
while (std::getline(file, line))
{
buf = users.getUserbyLogin(line);
if (buf != nullptr)
{
pals.push_back(buf);
}
}
update(username, pals);
return pals;
}
else
{
file.close();
std::ofstream file("friends\\F"+username+".txt");
update(username, pals);
file.close();
}
return getFriendsFromFile(username);
}
void findAndAddFriend(User * adder, std::string login)
{
std::vector adders_pals = adder->getFriends();
BDWorker users;
User* buf = users.getUserbyLogin(login);
for (auto f : adders_pals)
{
if (f->getLogin() == login)
{
std::cout << "User already in friend list...";
system("pause");
return;
}
}
if (buf != nullptr)
{
adders_pals.push_back(buf);
adder->setFriends(adders_pals);
}
else
{
std::cout << "User isn't exist";
system("pause");
return;
}
update(adder->getLogin(), adders_pals);
}
void findAndDelFriend(User * adder, int num)
{
std::vector adders_pals = adder->getFriends();
adders_pals.erase(adders_pals.begin() + num);
update(adder->getLogin(), adders_pals);
}
void update(std::string username, std::vector pals)
{
std::ofstream file("friends\\F"+username+".txt");
file << username << std::endl;
std::string line;
for (auto u : pals)
{
line = line + u->getLogin();
file << line << std::endl;
line.clear();
}
}
void deleteMe(User* me)
{
std::string filepath = "del friends\\F"+me->getLogin()+".txt";
system(filepath.c_str());
}
};
class Poster
{
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
public:
Poster(User * user){user->setPosts(getPostsFromFile(user->getLogin()));}
Poster(){}
std::vector getPostsFromFile(std::string username)
{
std::vector posts;
std::ifstream file("Posts\\"+username + ".txt");
if (file.is_open())
{
BDWorker users;
std::string line;
std::string header;
std::string text;
std::string date;
std::vector<:string> comment;
User * comment_author;
std::getline(file, line);
while (std::getline(file, line))
{
if (line[0] != '@')
{
if (line == "---")
{
posts.push_back(new Publication(header, text, date));
}
else
{
header = line;
_flushall();
std::getline(file, text);
std::getline(file, date);
}
}
else
{
if (line != "@@@")
{
header = split(line, '+')[1];
comment_author = users.getUserbyLogin(header);
_flushall();
std::getline(file, text);
std::getline(file, date);
if (comment_author != nullptr)
{
posts[posts.size()-1]->addComment(new Comment( split(text, '+')[1], split(date, '+')[1], comment_author));
}
}
}
}
return posts;
}
else
{
file.close();
std::ofstream file("Posts\\"+username+".txt");
update(username, posts);
file.close();
}
return getPostsFromFile(username);
}
void update(std::string username, std::vector posts)
{
std::ofstream file("Posts\\"+username+".txt");
file << "@@@" << std::endl;
std::vector comms_buff;
std::string line;
for (auto p : posts)
{
file << p->getHeader() << std::endl <getText() << std::endl << p->getDate() << std::endl << "---" << std::endl;
comms_buff = p->getComments();
for (auto c : comms_buff)
{
file << "@+"+c->getHeader() << std::endl << "@+"+c->getText() << std::endl << "@+"+c->getDate() << std::endl;
}
file << "@@@" << std::endl;
line.clear();
}
}
void deleteMe(User* me)
{
std::string filepath = "del Posts\\"+ me->getLogin() + ".txt";
system(filepath.c_str());
}
};
Файл “Paginator.h”.
Данный файл хранит класс, отвечающий за «пагинацию» объектов, а если конкретно, то за «пагинацию» публикаций пользователя.
#include
#include
#include
#include
#include "User_Post.h"
class Paginator
{
std::vector & all_items;
std::vector items;
int size;
int page;
int last_page;
int getAnswer(int size)
{
int answ;
do {
std::cout << "\nEnter item: ";
std::cin >> answ;
} while ((answ > size) || (answ < 1));
return answ;
}
void getNextItemToPages()
{
items.clear();
if (page != last_page-1)
page++;
else
{
std::cout << "This is the last page!" << std::endl;
system("pause");
}
for (int i = 0; (i < 10) && (i+page*10 < size); i++)
{
all_items[i+page*10]->show();
items.push_back(all_items[i+page*10]);
}
}
void getPreviousItemToPages()
{
if (page != 0)
{
page--;
}
else
{
std::cout << "This is the first page!" << std::endl;
system("pause");
}
items.clear();
for (int i = 0; (i < 10) && (i+page*10 < size); i++)
{
items.push_back(all_items[i+page*10]);
}
}
void toStart()
{
page = -1;
getNextItemToPages();
}
void toEnd()
{
page = last_page-2;
getNextItemToPages();
}
void showPage()
{
std::vector comms_buf;
for (int i = 0; i < items.size(); i++)
{
items[i]->show();
comms_buf = items[i]->getComments();
for (auto c : comms_buf)
{
c->show();
}
}
}
void addComment(User* guest)
{
int num;
if (guest->getComPer() == 1)
{
std::cout << "Enter Post number: ";
std::cin >> num;
num--;
std::string text;
_flushall();
std::getline(std::cin, text);
std::time_t t = std::time(nullptr);
char buf[64];
strftime(buf, sizeof(buf), "%d.%m.%Y", localtime(&t));
std::string date = buf;
all_items[page*10+num]->addComment(new Comment(text, date, guest));
}
else
{
std::cout << "User has forbidden to leave comments..." << std::endl;
system("pause");
}
}
public:
Paginator(std::vector & strs) : all_items(strs), size(strs.size()), page(-1)
{
last_page = size / 10;
if (size % 10 != 0) last_page++;
getNextItemToPages();
}
Paginator(){}
void watchPages(User* guest)
{
while (1)
{
system("cls");
guest->showProfile();
showPage();
std::cout << "1) Next Page" << std::endl << "2) Previous Page" << std::endl << "3) To Start" << std::endl << "4) To End" << std::endl << "5) Add Comment" << std::endl << "6) Step Back" << std::endl;
switch (getAnswer(6))
{
case 1:
getNextItemToPages();
break;
case 2:
getPreviousItemToPages();
break;
case 3:
toStart();
break;
case 4:
toEnd();
break;
case 5:
addComment(guest);
break;
case 6:
return;
break;
default:
break;
}
}
}
};
Файл «Screen.h»
Файл хранит объект, который строит начальный интерфейс и запускает программу.
#include "Menu.h"
class Client
{
Menu* menu_now;
User* login_user;
User* guest_user;
public:
Client(){menu_now = new StartMenu(login_user, guest_user);}
Client(){delete menu_now; delete login_user; delete guest_user;}
#include
#include
#include
#include "Paginator.h"
class UsersDataBase
{
private:
const std::string first_line_in_file = "login+password+hobbies+self-info+contacts+data+com_per";
std::string filepath;
std::vector users;
static UsersDataBase * p_instance;
UsersDataBase();
UsersDataBase(const UsersDataBase&);
UsersDataBase(std::string path) : filepath(path) {readUsersFullInfo();}
UsersDataBase& operator=(UsersDataBase&);
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
void readUsersFullInfo()
{
std::ifstream file(filepath);
if (file.is_open())
{
std::string line;
std::vector<:string> full_info;
std::getline(file, line);
while (std::getline(file, line))
{
full_info = split(line, '+');
users.push_back(new User(full_info[0], full_info[1], full_info[2], full_info[3], full_info[4], full_info[5], std::stoi(full_info[6])));
}
}
else
std::cout << "File missing!!!" << std::endl;
}
public:
static UsersDataBase * getUsersData(std::string path)
{
if(!p_instance)
p_instance = new UsersDataBase(path);
return p_instance;
}
std::string getPath()
{
return filepath;
}
User* find(std::string login, std::string pass)
{
for (int i = 0; i < users.size(); i++)
{
if ((users[i]->getLogin() == login) && (users[i]->getPass() == pass))
return users[i];
}
return nullptr;
}
void add(User* new_user)
{
std::ofstream file("log_pass.txt", std::ios_base::app);
if (file.is_open())
{
std::string line;
line = line + new_user->getLogin() + "+" + new_user->getPass() + "+" + new_user->getSelfInfo() + "+" + new_user->getContacts() + "+" + new_user->getHobbies() + "+" + new_user->getBirthdate() + "+" + std::to_string(new_user->getComPer());
file << line << std::endl;
}
else
{
std::cout << "File is Missing...";
system("pause");
}
users.push_back(new_user);
}
void update()
{
std::ofstream file("log_pass.txt");
file << first_line_in_file << std::endl;
std::string line;
for (auto u : users)
{
line = line + u->getLogin() + "+" + u->getPass() + "+" + u->getSelfInfo() + "+" + u->getContacts() + "+" + u->getHobbies() + "+" + u->getBirthdate() + "+" + std::to_string(u->getComPer());
file << line << std::endl;
line.clear();
}
}
User* findUserInFriendFiles(std::string login)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == login)
{
return users[i];
}
}
return nullptr;
}
void deleteMe(User* me)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == me->getLogin())
{
users.erase(users.begin() + i);
update();
return;
}
}
}
};
class BDWorker
{
UsersDataBase* bd_users;
public:
BDWorker(){bd_users = UsersDataBase::getUsersData("log_pass.txt");}
BDWorker(){}
User* find(std::string login, std::string pass)
{
return (bd_users->find(login, pass));
}
void add(User* new_user)
{
bd_users->add(new_user);
}
void update()
{
bd_users->update();
}
User* getUserbyLogin(std::string login)
{
return bd_users->findUserInFriendFiles(login);
}
void deleteMe(User* me)
{
bd_users->deleteMe(me);
}
};
class Friender
{
public:
Friender(User * user){user->setFriends(getFriendsFromFile(user->getLogin()));}
Friender(){}
std::vector getFriendsFromFile(std::string username)
{
std::vector pals;
std::ifstream file("friends\\F"+username+".txt");
if (file.is_open())
{
BDWorker users;
std::string line;
std::getline(file, line);
User* buf;
while (std::getline(file, line))
{
buf = users.getUserbyLogin(line);
if (buf != nullptr)
{
pals.push_back(buf);
}
}
update(username, pals);
return pals;
}
else
{
file.close();
std::ofstream file("friends\\F"+username+".txt");
update(username, pals);
file.close();
}
return getFriendsFromFile(username);
}
void findAndAddFriend(User * adder, std::string login)
{
std::vector adders_pals = adder->getFriends();
BDWorker users;
User* buf = users.getUserbyLogin(login);
for (auto f : adders_pals)
{
if (f->getLogin() == login)
{
std::cout << "User already in friend list...";
system("pause");
return;
}
}
if (buf != nullptr)
{
adders_pals.push_back(buf);
adder->setFriends(adders_pals);
}
else
{
std::cout << "User isn't exist";
system("pause");
return;
}
update(adder->getLogin(), adders_pals);
}
void findAndDelFriend(User * adder, int num)
{
std::vector adders_pals = adder->getFriends();
adders_pals.erase(adders_pals.begin() + num);
update(adder->getLogin(), adders_pals);
}
void update(std::string username, std::vector pals)
{
std::ofstream file("friends\\F"+username+".txt");
file << username << std::endl;
std::string line;
for (auto u : pals)
{
line = line + u->getLogin();
file << line << std::endl;
line.clear();
}
}
void deleteMe(User* me)
{
std::string filepath = "del friends\\F"+me->getLogin()+".txt";
system(filepath.c_str());
}
};
class Poster
{
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
public:
Poster(User * user){user->setPosts(getPostsFromFile(user->getLogin()));}
Poster(){}
#include
#include
#include
#include "Paginator.h"
class UsersDataBase
{
private:
const std::string first_line_in_file = "login+password+hobbies+self-info+contacts+data+com_per";
std::string filepath;
std::vector users;
static UsersDataBase * p_instance;
UsersDataBase();
UsersDataBase(const UsersDataBase&);
UsersDataBase(std::string path) : filepath(path) {readUsersFullInfo();}
UsersDataBase& operator=(UsersDataBase&);
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
void readUsersFullInfo()
{
std::ifstream file(filepath);
if (file.is_open())
{
std::string line;
std::vector<:string> full_info;
std::getline(file, line);
while (std::getline(file, line))
{
full_info = split(line, '+');
users.push_back(new User(full_info[0], full_info[1], full_info[2], full_info[3], full_info[4], full_info[5], std::stoi(full_info[6])));
}
}
else
std::cout << "File missing!!!" << std::endl;
}
public:
static UsersDataBase * getUsersData(std::string path)
{
if(!p_instance)
p_instance = new UsersDataBase(path);
return p_instance;
}
std::string getPath()
{
return filepath;
}
User* find(std::string login, std::string pass)
{
for (int i = 0; i < users.size(); i++)
{
if ((users[i]->getLogin() == login) && (users[i]->getPass() == pass))
return users[i];
}
return nullptr;
}
void add(User* new_user)
{
std::ofstream file("log_pass.txt", std::ios_base::app);
if (file.is_open())
{
std::string line;
line = line + new_user->getLogin() + "+" + new_user->getPass() + "+" + new_user->getSelfInfo() + "+" + new_user->getContacts() + "+" + new_user->getHobbies() + "+" + new_user->getBirthdate() + "+" + std::to_string(new_user->getComPer());
file << line << std::endl;
}
else
{
std::cout << "File is Missing...";
system("pause");
}
users.push_back(new_user);
}
void update()
{
std::ofstream file("log_pass.txt");
file << first_line_in_file << std::endl;
std::string line;
for (auto u : users)
{
line = line + u->getLogin() + "+" + u->getPass() + "+" + u->getSelfInfo() + "+" + u->getContacts() + "+" + u->getHobbies() + "+" + u->getBirthdate() + "+" + std::to_string(u->getComPer());
file << line << std::endl;
line.clear();
}
}
User* findUserInFriendFiles(std::string login)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == login)
{
return users[i];
}
}
return nullptr;
}
void deleteMe(User* me)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == me->getLogin())
{
users.erase(users.begin() + i);
update();
return;
}
}
}
};
class BDWorker
{
UsersDataBase* bd_users;
public:
BDWorker(){bd_users = UsersDataBase::getUsersData("log_pass.txt");}
BDWorker(){}#include
#include
#include
#include "Paginator.h"
class UsersDataBase
{
private:
const std::string first_line_in_file = "login+password+hobbies+self-info+contacts+data+com_per";
std::string filepath;
std::vector
static UsersDataBase * p_instance;
UsersDataBase();
UsersDataBase(const UsersDataBase&);
UsersDataBase(std::string path) : filepath(path) {readUsersFullInfo();}
UsersDataBase& operator=(UsersDataBase&);
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
void readUsersFullInfo()
{
std::ifstream file(filepath);
if (file.is_open())
{
std::string line;
std::vector<:string> full_info;
std::getline(file, line);
while (std::getline(file, line))
{
full_info = split(line, '+');
users.push_back(new User(full_info[0], full_info[1], full_info[2], full_info[3], full_info[4], full_info[5], std::stoi(full_info[6])));
}
}
else
std::cout << "File missing!!!" << std::endl;
}
public:
static UsersDataBase * getUsersData(std::string path)
{
if(!p_instance)
p_instance = new UsersDataBase(path);
return p_instance;
}
std::string getPath()
{
return filepath;
}
User* find(std::string login, std::string pass)
{
for (int i = 0; i < users.size(); i++)
{
if ((users[i]->getLogin() == login) && (users[i]->getPass() == pass))
return users[i];
}
return nullptr;
}
void add(User* new_user)
{
std::ofstream file("log_pass.txt", std::ios_base::app);
if (file.is_open())
{
std::string line;
line = line + new_user->getLogin() + "+" + new_user->getPass() + "+" + new_user->getSelfInfo() + "+" + new_user->getContacts() + "+" + new_user->getHobbies() + "+" + new_user->getBirthdate() + "+" + std::to_string(new_user->getComPer());
file << line << std::endl;
}
else
{
std::cout << "File is Missing...";
system("pause");
}
users.push_back(new_user);
}
void update()
{
std::ofstream file("log_pass.txt");
file << first_line_in_file << std::endl;
std::string line;
for (auto u : users)
{
line = line + u->getLogin() + "+" + u->getPass() + "+" + u->getSelfInfo() + "+" + u->getContacts() + "+" + u->getHobbies() + "+" + u->getBirthdate() + "+" + std::to_string(u->getComPer());
file << line << std::endl;
line.clear();
}
}
User* findUserInFriendFiles(std::string login)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == login)
{
return users[i];
}
}
return nullptr;
}
void deleteMe(User* me)
{
for (int i = 0; i < users.size(); i++)
{
if (users[i]->getLogin() == me->getLogin())
{
users.erase(users.begin() + i);
update();
return;
}
}
}
};
class BDWorker
{
UsersDataBase* bd_users;
public:
BDWorker(){bd_users = UsersDataBase::getUsersData("log_pass.txt");}
User* find(std::string login, std::string pass)
{
return (bd_users->find(login, pass));
}
void add(User* new_user)
{
bd_users->add(new_user);
}
void update()
{
bd_users->update();
}
User* getUserbyLogin(std::string login)
{
return bd_users->findUserInFriendFiles(login);
}
void deleteMe(User* me)
{
bd_users->deleteMe(me);
}
};
class Friender
{
public:
Friender(User * user){user->setFriends(getFriendsFromFile(user->getLogin()));}
{
std::vector
std::ifstream file("friends\\F"+username+".txt");
if (file.is_open())
{
BDWorker users;
std::string line;
std::getline(file, line);
User* buf;
while (std::getline(file, line))
{
buf = users.getUserbyLogin(line);
if (buf != nullptr)
{
pals.push_back(buf);
}
}
update(username, pals);
return pals;
}
else
{
file.close();
std::ofstream file("friends\\F"+username+".txt");
update(username, pals);
file.close();
}
return getFriendsFromFile(username);
}
void findAndAddFriend(User * adder, std::string login)
{
std::vector
BDWorker users;
User* buf = users.getUserbyLogin(login);
for (auto f : adders_pals)
{
if (f->getLogin() == login)
{
std::cout << "User already in friend list...";
system("pause");
return;
}
}
if (buf != nullptr)
{
adders_pals.push_back(buf);
adder->setFriends(adders_pals);
}
else
{
std::cout << "User isn't exist";
system("pause");
return;
}
update(adder->getLogin(), adders_pals);
}
void findAndDelFriend(User * adder, int num)
{
std::vector
adders_pals.erase(adders_pals.begin() + num);
update(adder->getLogin(), adders_pals);
}
void update(std::string username, std::vector
{
std::ofstream file("friends\\F"+username+".txt");
file << username << std::endl;
std::string line;
for (auto u : pals)
{
line = line + u->getLogin();
file << line << std::endl;
line.clear();
}
}
void deleteMe(User* me)
{
std::string filepath = "del friends\\F"+me->getLogin()+".txt";
system(filepath.c_str());
}
};
class Poster
{
std::vector<:string> split(const std::string &s, char delim)
{
std::vector<:string> result;
std::stringstream ss(s);
std::string item;
while (std::getline (ss, item, delim)) {
result.push_back (item);
}
return result;
}
public:
Poster(User * user){user->setPosts(getPostsFromFile(user->getLogin()));}
std::vector
{
std::vector
std::ifstream file("Posts\\"+username + ".txt");
if (file.is_open())
{
BDWorker users;
std::string line;
std::string header;
std::string text;
std::string date;
std::vector<:string> comment;
User * comment_author;
std::getline(file, line);
while (std::getline(file, line))
{
if (line[0] != '@')
{
if (line == "---")
{
posts.push_back(new Publication(header, text, date));
}
else
{
header = line;
_flushall();
std::getline(file, text);
std::getline(file, date);
}
}
else
{
if (line != "@@@")
{
header = split(line, '+')[1];
comment_author = users.getUserbyLogin(header);
_flushall();
std::getline(file, text);
std::getline(file, date);
if (comment_author != nullptr)
{
posts[posts.size()-1]->addComment(new Comment( split(text, '+')[1], split(date, '+')[1], comment_author));
}
}
}
}
return posts;
}
else
{
file.close();
std::ofstream file("Posts\\"+username+".txt");
update(username, posts);
file.close();
}
return getPostsFromFile(username);
}
void update(std::string username, std::vector
{
std::ofstream file("Posts\\"+username+".txt");
file << "@@@" << std::endl;
std::vector
std::string line;
for (auto p : posts)
{
file << p->getHeader() << std::endl <
comms_buff = p->getComments();
for (auto c : comms_buff)
{
file << "@+"+c->getHeader() << std::endl << "@+"+c->getText() << std::endl << "@+"+c->getDate() << std::endl;
}
file << "@@@" << std::endl;
line.clear();
}
}
void deleteMe(User* me)
{
std::string filepath = "del Posts\\"+ me->getLogin() + ".txt";
system(filepath.c_str());
}
};
Файл “Paginator.h”.
Данный файл хранит класс, отвечающий за «пагинацию» объектов, а если конкретно, то за «пагинацию» публикаций пользователя.
#include
#include
#include
#include
#include "User_Post.h"
class Paginator
{
std::vector
std::vector
int size;
int page;
int last_page;
int getAnswer(int size)
{
int answ;
do {
std::cout << "\nEnter item: ";
std::cin >> answ;
} while ((answ > size) || (answ < 1));
return answ;
}
void getNextItemToPages()
{
items.clear();
if (page != last_page-1)
page++;
else
{
std::cout << "This is the last page!" << std::endl;
system("pause");
}
for (int i = 0; (i < 10) && (i+page*10 < size); i++)
{
all_items[i+page*10]->show();
items.push_back(all_items[i+page*10]);
}
}
void getPreviousItemToPages()
{
if (page != 0)
{
page--;
}
else
{
std::cout << "This is the first page!" << std::endl;
system("pause");
}
items.clear();
for (int i = 0; (i < 10) && (i+page*10 < size); i++)
{
items.push_back(all_items[i+page*10]);
}
}
void toStart()
{
page = -1;
getNextItemToPages();
}
void toEnd()
{
page = last_page-2;
getNextItemToPages();
}
void showPage()
{
std::vector
for (int i = 0; i < items.size(); i++)
{
items[i]->show();
comms_buf = items[i]->getComments();
for (auto c : comms_buf)
{
c->show();
}
}
}
void addComment(User* guest)
{
int num;
if (guest->getComPer() == 1)
{
std::cout << "Enter Post number: ";
std::cin >> num;
num--;
std::string text;
_flushall();
std::getline(std::cin, text);
std::time_t t = std::time(nullptr);
char buf[64];
strftime(buf, sizeof(buf), "%d.%m.%Y", localtime(&t));
std::string date = buf;
all_items[page*10+num]->addComment(new Comment(text, date, guest));
}
else
{
std::cout << "User has forbidden to leave comments..." << std::endl;
system("pause");
}
}
public:
Paginator(std::vector
{
last_page = size / 10;
if (size % 10 != 0) last_page++;
getNextItemToPages();
}
};
Файл «main.cpp»
Главный файл, создает экземпляр объекта, активирующий рабочую область программы.
#include
#include
#include
#include "Screen.h"
int main()
{
Client * m = new Client();
return 0;
}
Пример работы программы:
Входим под существующим юзером
Открывается профиль пользователя, в нем открываем меню публикаций
Открываем наши посты, считанные с файла.
Вывод
В процессе реализации расчетно-графического задания я изучил паттерны проектирования.
В данной работе были использованы паттерны: одиночка и мост. Использовал одиночку для получения глобального доступа к регистрационным данным пользователя. Мост был задет в производных классах Menu, так как я манипулировал классом User с помощью Menu.
Список литературы
-
Паттерны проектирования [Электронный ресурс]. – Режим доступа: https://refactoring.guru/ru/design-patterns/cpp, свободный – (25.12.2020). -
Лекционный материал по предмету «Объектно-ориентированное программирование»