/
awake
/
Final_lesson_C
Обзор
Документация
Войти
/
awake
/
Final_lesson_C
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
main.cpp
316 строк
15 KB
awake
update .gitignore
03 июн 2025, 09:59
03 июн 2025, 09:59
e5734d1
Код
Авторство
О чём код?
#include <iostream> #include <vector> #include <string> #include <fstream> #include <sstream> #include <algorithm> #include <iomanip> #include <tabulate/table.hpp> using namespace tabulate; // Вспомогательная функция: удаляет кавычки с начала и конца строки, если они есть. std::string trimQuotes(const std::string& str) { if (str.size() >= 2 && str.front() == '"' && str.back() == '"') { return str.substr(1, str.size() - 2); } return str; } // Вспомогательная функция: форматирует число, добавляя разделители тысяч (например, 1,000,000). std::string formatWithCommas(unsigned int n) { std::string s = std::to_string(n); int len = s.length(); if (len <= 3) return s; std::string result; int count = 0; for (int i = len - 1; i >= 0; --i) { result.push_back(s[i]); count++; if (count % 3 == 0 && i != 0) { result.push_back(','); } } std::reverse(result.begin(), result.end()); return result; } // Структура для хранения информации о производителе программного обеспечения. struct SoftwareManufacturer { std::string name; // Название производителя std::string country; // Страна регистрации std::string website; // Веб-сайт компании unsigned int productCount; // Количество разработанных продуктов unsigned int salesVolume; // Объем продаж (в условных единицах) float avgProductPrice; // Средняя цена продукта }; // Класс для работы с базой данных производителей программного обеспечения. // Позволяет загружать, сохранять, отображать, добавлять, удалять, // сортировать и искать записи. class Database { std::vector<SoftwareManufacturer> records; // Вектор для хранения всех записей public: // Загружает данные о производителях из указанного CSV-файла. // Возвращает true в случае успеха, false при ошибке открытия файла. bool loadFromCSV(const std::string &filename) { std::ifstream file(filename); if (!file.is_open()) return false; records.clear(); std::string line; getline(file, line); while (getline(file, line)) { std::stringstream ss(line); SoftwareManufacturer rec; std::string field; getline(ss, field, ','); rec.name = trimQuotes(field); getline(ss, field, ','); rec.country = trimQuotes(field); getline(ss, field, ','); rec.website = trimQuotes(field); getline(ss, field, ','); field = trimQuotes(field); rec.productCount = std::stoul(field); getline(ss, field, ','); field = trimQuotes(field); rec.salesVolume = std::stoul(field); getline(ss, field, ','); field = trimQuotes(field); rec.avgProductPrice = std::stof(field); records.push_back(rec); } return true; } // Сохраняет текущие данные базы данных в указанный CSV-файл. // Возвращает true в случае успеха, false при ошибке открытия файла. bool saveToCSV(const std::string &filename) const { std::ofstream file(filename); if (!file.is_open()) return false; file << "Название,Страна,Сайт,Кол-во продуктов,Объем продаж,Средняя цена\n"; for (const auto &r: records) { file << r.name << ',' << r.country << ',' << r.website << ',' << r.productCount << ',' << r.salesVolume << ',' << r.avgProductPrice << '\n'; } return true; } // Выводит все записи базы данных в виде красиво отформатированной таблицы. void printTable() const { if (records.empty()) { std::cout << "База данных пуста.\n"; return; } Table table; // Добавляем заголовки столбцов table.add_row({"№", "Название", "Страна", "Сайт", "Кол-во продуктов", "Объем продаж", "Средняя цена"}); // Добавляем строки данных, включая нумерацию for (size_t i = 0; i < records.size(); ++i) { const auto &r = records[i]; std::string productCountStr = formatWithCommas(r.productCount); std::string salesVolumeStr = formatWithCommas(r.salesVolume); std::stringstream ss; ss << std::fixed << std::setprecision(2) << r.avgProductPrice; std::string avgPriceStr = ss.str(); table.add_row({std::to_string(i + 1), r.name, r.country, r.website, productCountStr, salesVolumeStr, avgPriceStr}); } // Настраиваем внешний вид таблицы (например, жирный шрифт для заголовков) table.format() .font_style({tabulate::FontStyle::bold}); // Устанавливаем выравнивание и поддержку многобайтовых символов для каждого столбца table.column(0).format() .font_align(tabulate::FontAlign::center) .multi_byte_characters(true); // № table.column(1).format() .font_align(tabulate::FontAlign::left) .multi_byte_characters(true); // Название table.column(2).format() .font_align(tabulate::FontAlign::left) .multi_byte_characters(true); // Страна table.column(3).format() .font_align(tabulate::FontAlign::left) .multi_byte_characters(true); // Сайт table.column(4).format() .font_align(tabulate::FontAlign::center) .multi_byte_characters(true); // Кол-во продуктов table.column(5).format() .font_align(tabulate::FontAlign::center) .multi_byte_characters(true); // Объем продаж table.column(6).format() .font_align(tabulate::FontAlign::center) .multi_byte_characters(true); // Средняя цена // Выводим готовую таблицу в консоль std::cout << table << std::endl; } // Добавляет новую запись о производителе в базу данных. void addRecord(const SoftwareManufacturer &rec) { records.push_back(rec); } // Удаляет запись из базы данных по её индексу (начиная с 0). // Если индекс некорректен, ничего не происходит. void deleteRecord(size_t idx) { if (idx < records.size()) records.erase(records.begin() + idx); } // Сортирует все записи в базе данных по названию производителя в алфавитном порядке. void sortByName() { std::sort(records.begin(), records.end(), [](const auto &a, const auto &b) { return a.name < b.name; }); } // Ищет производителя по его точному названию. // Возвращает индекс найденной записи (начиная с 0) или -1, если производитель не найден. int findByName(const std::string &name) const { for (size_t i = 0; i < records.size(); ++i) { if (records[i].name == name) return i; } return -1; } // Выбирает и выводит производителей, чей объем продаж находится в заданном диапазоне. void selectBySalesVolume(unsigned int minV, unsigned int maxV) const { for (const auto &r: records) { if (r.salesVolume >= minV && r.salesVolume <= maxV) { std::cout << r.name << " (" << r.salesVolume << ")\n"; } } } // Индивидуальная задача 1: Увеличивает среднюю цену продуктов // для производителей, у которых объем продаж превышает V, на P процентов. void increasePriceIfSalesAbove(unsigned int V, float P) { for (auto &r: records) { if (r.salesVolume > V) { r.avgProductPrice *= (1.0f + P / 100.0f); } } } // Индивидуальная задача 2: Разделяет текущую базу данных на две новые: // одна содержит производителей из указанной страны, другая - всех остальных. void splitByCountry(const std::string &country, Database &db1, Database &db2) const { db1.records.clear(); db2.records.clear(); for (const auto &r: records) { if (r.country == country) db1.records.push_back(r); else db2.records.push_back(r); } } // Возвращает текущее количество записей в базе данных. size_t size() const { return records.size(); } }; // Выводит основное меню программы в консоль. void printMenu() { std::cout << "\nМеню:\n"; std::cout << "1. Загрузить БД из файла\n"; std::cout << "2. Сохранить БД в файл\n"; std::cout << "3. Просмотреть БД\n"; std::cout << "4. Добавить запись\n"; std::cout << "5. Удалить запись\n"; std::cout << "6. Сортировать по названию\n"; std::cout << "7. Поиск по названию\n"; std::cout << "8. Выборка по объему продаж\n"; std::cout << "9. Индивидуальная задача 1\n"; std::cout << "10. Индивидуальная задача 2\n"; std::cout << "0. Выход\n"; } // Главная функция программы: реализует интерактивное меню // для управления базой данных производителей программного обеспечения. int main() { Database db; while (true) { printMenu(); int cmd; std::cout << "Выберите пункт: "; std::cin >> cmd; if (cmd == 0) break; // Выход из программы if (cmd == 1) { // Загрузка БД из файла std::string fname; std::cout << "Имя файла: "; std::cin.ignore(); // Очистка буфера перед getline getline(std::cin, fname); if (db.loadFromCSV(fname)) std::cout << "Загружено!\n"; else std::cout << "Ошибка загрузки!\n"; } else if (cmd == 2) { // Сохранение БД в файл std::string fname; std::cout << "Имя файла: "; std::cin.ignore(); // Очистка буфера перед getline getline(std::cin, fname); if (db.saveToCSV(fname)) std::cout << "Сохранено!\n"; else std::cout << "Ошибка сохранения!\n"; } else if (cmd == 3) { // Просмотр БД db.printTable(); } else if (cmd == 4) { // Добавление новой записи SoftwareManufacturer rec; std::cout << "Название: "; std::cin.ignore(); // Очистка буфера перед getline getline(std::cin, rec.name); std::cout << "Страна: "; getline(std::cin, rec.country); std::cout << "Сайт: "; getline(std::cin, rec.website); std::cout << "Кол-во продуктов: "; std::cin >> rec.productCount; std::cout << "Объем продаж: "; std::cin >> rec.salesVolume; std::cout << "Средняя цена: "; std::cin >> rec.avgProductPrice; db.addRecord(rec); } else if (cmd == 5) { // Удаление записи size_t idx; std::cout << "Номер записи (с 0): "; std::cin >> idx; db.deleteRecord(idx); } else if (cmd == 6) { // Сортировка записей по названию db.sortByName(); std::cout << "Отсортировано!\n"; } else if (cmd == 7) { // Поиск записи по названию std::string name; std::cout << "Название: "; std::cin.ignore(); // Очистка буфера перед getline getline(std::cin, name); int idx = db.findByName(name); if (idx >= 0) std::cout << "Найдено: " << idx << "\n"; else std::cout << "Не найдено!\n"; } else if (cmd == 8) { // Выборка записей по диапазону объема продаж unsigned int minV, maxV; std::cout << "Мин. объем: "; std::cin >> minV; std::cout << "Макс. объем: "; std::cin >> maxV; db.selectBySalesVolume(minV, maxV); } else if (cmd == 9) { // Выполнение индивидуальной задачи 1 unsigned int V; float P; std::cout << "V: "; std::cin >> V; std::cout << "P (процентов): "; std::cin >> P; db.increasePriceIfSalesAbove(V, P); std::cout << "Цены обновлены!\n"; } else if (cmd == 10) { // Выполнение индивидуальной задачи 2 std::string country; std::cout << "Страна: "; std::cin.ignore(); // Очистка буфера перед getline getline(std::cin, country); Database db1, db2; db.splitByCountry(country, db1, db2); std::cout << "\nПроизводители из страны " << country << ":\n"; db1.printTable(); std::cout << "\nОстальные производители:\n"; db2.printTable(); } } return 0; }