Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <iomanip>
- #include <fstream>
- #include <string>
- #include <unordered_map>
- using namespace std;
- template<typename T>
- T integer(const char* msg = ">>> ") {
- cout << msg;
- unsigned value;
- cin >> value;
- cin.ignore(numeric_limits<streamsize>::max(), '\n');
- return static_cast<T>(value);
- }
- class Cataloge {
- public:
- explicit Cataloge(const string& path) : path(path) {
- load();
- }
- ~Cataloge() {
- save();
- }
- void load() {
- ifstream inp{ path };
- if (inp.is_open()) {
- string key;
- short value;
- while (inp >> key >> value) {
- replace(key.begin(), key.end(), '_', ' ');
- box.insert({ key, value });
- }
- inp.close();
- if (box.empty()) {
- puts("Каталог найден, но не содержит записей!");
- }
- } else {
- puts("Путь к файлу каталога не найден!\nПрограмма создала пустой каталог.");
- }
- }
- void save() {
- ofstream out{ path };
- if (out.is_open()) {
- for (auto& [key, value] : box) {
- auto tmp = key;
- replace(tmp.begin(), tmp.end(), ' ', '_');
- out << tmp << ' ' << value << '\n';
- }
- out.close();
- } else {
- puts("Программе не удалось сохранить данные!");
- }
- }
- void show()const {
- auto lambda = [](const pair<string, short>& a, const pair<string, short>& b) {
- return a.first.length() < b.first.length();
- };
- auto width = max_element(box.begin(), box.end(), lambda)->first.length() + 1U;
- for (const auto& [key, value] : box) {
- cout << left << setw(width) << key << ' ' << value << '\n';
- }
- }
- void oldest() {
- auto lambda = [](const pair<string, short>& a, const pair<string, short>& b) {
- return a.second < b.second;
- };
- auto old = min_element(box.begin(), box.end(), lambda);
- cout << old->first << ' ' << old->second << '\n';
- }
- void add_record(pair<string, short>&& rec) {
- box.insert(box.end(), rec);
- }
- void erase_record(size_t&& pos) {
- auto n = 0U;
- for (auto it = box.begin(); it != box.end(); ++it) {
- if (++n == pos) {
- box.erase(it);
- break;
- }
- }
- }
- private:
- string path;
- unordered_multimap<string, short> box;
- };
- class UI {
- public:
- int run(Cataloge& cat) {
- auto repeat = true;
- do {
- puts("\tВыбор действия:");
- for (const auto& msg : messages) cout << msg << '\n';
- switch (integer<Menu>()) {
- case Menu::Load: cat.load(); break;
- case Menu::Show: cat.show(); break;
- case Menu::Oldest: cat.oldest(); break;
- case Menu::Add: cat.add_record(record()); break;
- case Menu::Erase: cat.erase_record(position()); break;
- case Menu::Save: cat.save(); break;
- case Menu::Exit: repeat = false; break;
- default: puts("Неверный выбор!");
- }
- puts("");
- } while (repeat);
- return 0;
- }
- private:
- enum class Menu {
- Load = 1, Show, Oldest, Add, Erase, Save, Exit
- };
- inline static const char* messages[]{
- "1. Загрузка данных из файла",
- "2. Вывод данных в виде таблицы",
- "3. Вывод самого первого журнала по дате",
- "4. Добавить запись",
- "5. Удаление записи по её номеру",
- "6. Сохранение данных в файл",
- "7. Выход из программы",
- };
- pair<string, short> record() {
- pair<string, short> rec;
- cout << "Введите название журнала: ";
- getline(cin, rec.first);
- rec.second = integer<short>("Введите год издания: ");
- return rec;
- }
- size_t position() {
- return integer<size_t>("Введите номер удаляемой записи: ");
- }
- };
- int main() {
- system("chcp 1251 > nul");
- string path{ "D:\\magazine.txt" };
- Cataloge cat{ path };
- UI ui;
- return ui.run(cat);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement