栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

使用C++标准库解析ini格式文件,只提供解析后的表和写入函数,查询、修改等功能可自行添加函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用C++标准库解析ini格式文件,只提供解析后的表和写入函数,查询、修改等功能可自行添加函数

rw_ini_base

使用C++标准库解析ini格式文件,只提供解析后的表和写入函数,查询、修改等功能可自行添加函数
个人博客地址:https://www.blog.hiyj.cn/article/detail/114
源码链接:https://github.com/WindSnowLi/rw_ini_base

类型说明 节点基类
    
    class node_base {
    public:
        // 行上注释
        std::vector line_up_explain{};
        // 行尾注释
        std::string line_tail_explain{};
    };
section类
    
    class section : public node_base {
    public:
        // section名字
        std::string name{};
        // 所属键值表
        std::vector table{};

        section() = default;

        explicit section(std::string name) : name(std::move(name)) {}

        bool operator==(const section &s) const {
            return name == s.name;
        }
    };
键值对类
    
    class key_value : public node_base {
    public:
        // 键
        std::string key{};
        // 值
        std::string value{};

        bool operator==(const key_value &k_v) const {
            return key == k_v.key;
        }
    };
封装问题 示例
class rw_ini_test : public rw_ini::rw_ini_base {
public:
    explicit rw_ini_test(const std::string &ini_path) : rw_ini::rw_ini_base(ini_path) {}
    // 从rw_ini::rw_ini_base类继承到了解析结果集std::vector
s_list // 以及写入函数rw_ini::rw_ini_base::write() // 可以封装自己喜欢的api };
说明

可通过 std::vector

s_list 直接查找 section 对象并或其所属键值对列表,可直接进行修改值操作,修改完成后可执行写入函数写入文件。

完整实现

#ifndef RW_INI_RW_INI_base_H
#define RW_INI_RW_INI_base_H

#include 
#include 
#include 
#include 

// 命名空间
namespace rw_ini
{

    class key_value;

    class section;

    
    class node_base
    {
    public:
        // 行上注释
        std::vector line_up_explain{};
        // 行尾注释
        std::string line_tail_explain{};
    };

    
    class section : public node_base
    {
    public:
        // section名字
        std::string name{};
        // 所属键值表
        std::vector table{};

        section() = default;

        explicit section(std::string name) : name(std::move(name)) {}

        bool operator==(const section &s) const
        {
            return name == s.name;
        }
    };

    
    class key_value : public node_base
    {
    public:
        // 键
        std::string key{};
        // 值
        std::string value{};

        bool operator==(const key_value &k_v) const
        {
            return key == k_v.key;
        }
    };

    
    class rw_ini_base
    {
    private:
        // ini文件路径
        std::string ini_path{};

        // 节点上部注释缓冲区
        std::vector line_up_explain_buff{};

        
        void parse_line(const std::string &line);

        
        void parse_line_section(const std::string &line, int start = 0);

        
        void parse_line_map(const std::string &line, int start = 0);

        
        void parse_line_key(const std::string &line, int start = 0);

        
        void parse_line_value(const std::string &line, int start = 0);

        
        void parse_line_up_explain(const std::string &line, int start = 0);

        
        void parse_line_tail_explain(const std::string &line, int start = 0);

    public:
        
        explicit rw_ini_base(const std::string &ini_path);

        // 整体内容表
        std::vector
s_list; // 文件尾部注释 std::vector tail_explain{}; void write(); }; } rw_ini::rw_ini_base::rw_ini_base(const std::string &ini_path) { this->ini_path = ini_path; std::ifstream fp(this->ini_path, std::ios::in); std::string line; while (std::getline(fp, line)) { this->parse_line(line); } fp.close(); this->line_up_explain_buff.swap(this->tail_explain); } void rw_ini::rw_ini_base::parse_line(const std::string &line) { // 空行直接略过 if (line.empty() || line[0] == 'r' || line[0] == 'n') { return; } // 遍历一行,寻找第一个有效字符位置 for (int i = 0; i < line.size(); i++) { // 略过开头空格 if (line[i] == ' ') { continue; // 读取到[视为该行为section行 } else if (line[i] == '[') { this->parse_line_section(line, i); // 读取到;或#视为该行为行上注释 } else if (line[i] == ';' || line[i] == '#') { this->parse_line_up_explain(line, i); } else { //除此之外为键值对行 this->parse_line_map(line, i); } break; } } void rw_ini::rw_ini_base::parse_line_section(const std::string &line, int start) { // parse_line已读取到[,开始从下一个字符标记 int i = start + 1; // 标记至]字符 for (; i < line.length(); ++i) { if (line[i] == ']') { break; } } // 截取[]区间内的字符 auto s = section(line.substr(start + 1, i - start - 1)); // 如果行上注释不为空,则所属于当前section if (!this->line_up_explain_buff.empty()) { s.line_up_explain.swap(this->line_up_explain_buff); } // 列表里放入sectio this->s_list.emplace_back(s); // 继续向后检索,查看是否有注释 for (; i < line.length(); ++i) { if (line[i] == ';' || line[i] == '#') { // 解析注释 this->parse_line_tail_explain(line, i); break; } } } void rw_ini::rw_ini_base::parse_line_map(const std::string &line, int start) { // 已由parse_line进行了排除前导空格操作,识别到了key的第一个字符 this->parse_line_key(line, start); // 如果行上注释不为空,则所属于当前key_value if (!this->line_up_explain_buff.empty()) { this->s_list.rbegin()->table.rbegin()->line_up_explain.swap(this->line_up_explain_buff); } } void rw_ini::rw_ini_base::parse_line_key(const std::string &line, int start) { // parse_line_map已识别至key的第一个有效字符,key_end_pos为key的结束位置 int i = start, key_end_pos = start; // key缓冲字符 std::string key_buff; for (; i < line.length(); ++i) { // key的读取截止到=之前 if (line[i] != '=') { key_buff.push_back(line[i]); } else { break; } // =之前的空格不计 if (line[i] != ' ') { key_end_pos = i; } } // 创建新的key_value对象 this->s_list.rbegin()->table.emplace_back(key_value()); // 截取除末尾空格,写入key this->s_list.rbegin()->table.rbegin()->key = key_buff.substr(0, key_end_pos - start + 1); //接下来识别value this->parse_line_value(line, i); } void rw_ini::rw_ini_base::parse_line_value(const std::string &line, int start) { std::string value_buff; // 已由parse_line_key识别到了= int i = start; // =后为value开始位置,value_end_pos为value结束位置标记 int value_start_pos = ++i, value_end_pos = 0; // 去除value前导空格 for (; i < line.length(); ++i) { if (line[i] == ' ') { continue; } break; } for (; i < line.length(); ++i) { // 不是注释标识符则视为value字符 if (line[i] != ';' && line[i] != '#') { value_buff.push_back(line[i]); } else { // 读到注释标识符移交给parse_line_tail_explain处理 this->parse_line_tail_explain(line, i); break; } // 忽略末尾空格 if (line[i] != ' ') { value_end_pos = i; } } // 截取除末尾空格的value auto value = value_buff.substr(0, value_end_pos - value_start_pos); // 如果自带引号,则去掉引号 if (*value.begin() == '"' && *value.rbegin() == '"') { value = value.substr(1, value.length() - 2); } this->s_list.rbegin()->table.rbegin()->value = value; } void rw_ini::rw_ini_base::parse_line_up_explain(const std::string &line, int start) { // 去除前导空格 int i = start; for (; i < line.length(); ++i) { if (line[i] == ' ') { continue; } break; } // 行上注释直接追加至行上注释缓冲区 this->line_up_explain_buff.emplace_back(line.substr(i + 1)); } void rw_ini::rw_ini_base::parse_line_tail_explain(const std::string &line, int start) { // 如果section键值对表为空,则行尾注释属于最后一个section if (this->s_list.rbegin()->table.empty()) { this->s_list.rbegin()->line_tail_explain = line.substr(start + 1); } else { // 否则属于最后一个键值对 this->s_list.rbegin()->table.rbegin()->line_tail_explain = line.substr(start + 1); } } void rw_ini::rw_ini_base::write() { std::stringstream ss; for (auto &&i : this->s_list) { for (auto &&j : i.line_up_explain) { ss << "# " << j << 'n'; } ss << '[' << i.name << ']'; if (!i.line_tail_explain.empty()) { ss << 't' << i.line_tail_explain; } ss << 'n'; for (auto &&j : i.table) { for (auto &&k : j.line_up_explain) { ss << "# " << k << 'n'; } ss << j.key << " = " << j.value; if (!j.line_tail_explain.empty()) { ss << 't' << i.line_tail_explain; } ss << 'n'; } ss << "n"; } std::ofstream fp(this->ini_path, std::ios::trunc); fp << ss.str(); fp.close(); } #endif //RW_INI_RW_INI_base_H
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/290976.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号