/
AirLexa
/
04
Обзор
Документация
Войти
/
AirLexa
/
04
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
INIParser/INIParser.cpp
121 строка
5 KB
AirLexa
update: INIParser.cpp
12 мар 2026, 21:54
Верифицирован
12 мар 2026, 21:54
209c424
Код
Авторство
О чём код?
#include <iostream> #include <fstream> #include <variant> #include <string> #include "INIParser.h" static std::string& trim(std::string& s) { const char* t = " \t\n\r"; s.erase(s.find_last_not_of(t) + 1); s.erase(0, s.find_first_not_of(t)); return s; } INIParser::INIParser(std::string name_file) { std::string res = scan_file(name_file); if (!res.empty()) throw std::runtime_error(res); }; std::string INIParser::scan_file(std::string& name_file) { std::ifstream file(name_file); if (!file.is_open()) // проверка на доступ к файлу return "Ошибка открытия файла: " + name_file + "!"; std::string line = "", sec = ""; std::size_t num_str = 0; while (std::getline(file, line)) { num_str++; if (trim(line).empty()) continue; // пустая строка std::size_t pos = line.find(';'); if (pos != std::string::npos) { // нашли коментарий if (pos == 0) continue; // если первый, то вся строка коментарий line = line.substr(0, pos); // иначе игнорируем все за ';' символом } pos = line.find('['); // ищем секции if (pos != std::string::npos) { // нашли начало секции std::size_t last = line.find(']'); // ищем конец секции if (last == std::string::npos || // нет конца или он перепутан last < pos) return "Ошибка структуры файла: " + name_file + "! Некорректный заголовок секции. Строка: " + std::to_string(num_str) + " {" + line + "}"; sec = line.substr(pos + 1, last - 1); // новое имя секции continue; } if (sec.empty()) // нет имени секции, а пошли значения, это ошибка return "Ошибка структуры файла: " + name_file + "! Отсутсвует имя секции. Строка: " + std::to_string(num_str) + " {" + line + "}"; pos = trim(line).find('='); // осталось найти значения if (pos == std::string::npos) // нет символа '=', это ошибка return "Ошибка структуры файла: " + name_file + "!\nОтсутсвует знак '='. Строка: " + std::to_string(num_str) + " {" + line + "}"; if (pos == 0) // нет имени ключа, это ошибка return "Ошибка структуры файла: " + name_file + "! Отсутсвует имя ключа у значения. Строка: " + std::to_string(num_str) + " {" + line + "}"; std::string key = line.substr(0, pos); std::string val = line.substr(pos + 1); data.insert_or_assign(sec + '.' + trim(key), trim(val)); } file.close(); return ""; } void INIParser::print(std::string key) { if (key.empty()) // печатаем все, что есть for (const auto& [s, v] : data) std::cout << s << "\t" << v << std::endl; else { // печатаем только указанную секцию int pos = key.find('.'); std::string sec = key.substr(0, pos++); std::cout << sec << ":\n"; for (const auto& [s, v] : data) { if (s.find(sec) == 0) // совпало, это наша секция std::cout << s.substr(pos) << " = \t" << v << std::endl; } } } template<> std::string INIParser::get_value(const std::string& key) { auto it = data.find(key); if (it != data.end()) // есть такой ключ, отправляем значение return data[key]; else throw std::runtime_error("Ошибка! Такая секция/ключ не найден!"); return ""; } template<> int INIParser::get_value(const std::string& key) { auto it = data.find(key); if (it == data.end()) // не нашли такого ключа throw std::runtime_error("Ошибка! Такая секция/ключ не найден!"); else // есть такой ключ, отправляем значение try { return std::stoi(data[key]); } catch (const std::exception& e) {} throw std::runtime_error("Ошибка! Это не целое число!"); } template<> double INIParser::get_value(const std::string& key) { auto it = data.find(key); if (it == data.end()) // не нашли такого ключа throw std::runtime_error("Ошибка! Такая секция/ключ не найден!"); else // есть такой ключ, отправляем значение try { return std::stod(data[key]); } catch (const std::exception& e) {} throw std::runtime_error("Ошибка! Это не дробное число!"); }