C++利用boost库加载配置文件参数

C++利用boost库加载配置文件参数

  • 我们如果要从外部配置文件加载参数,以便提高应用程序的灵活性和可维护性时。
  • 通过外部配置文件,程序可以在无需重新编译的情况下轻松地调整配置参数。

如果有config.ini文件

[database]
host = localhost
port = 3306
user = root
password = rootpassword

[logging]
level = debug
file = log.txt

可以利用两个类来描述这个文件并保存他们的键值对

数据结构的描述

  1. SectionInfo

    • SectionInfo 类用于存储单个配置节(section)中的键值对(例如存储host、port…),其中键和值均为字符串类型。内部实现了一个 std::map<std::string, std::string> 来存储这些键值对。
    • SectionInfo 类主要用于处理配置文件中某个section 的信息,允许通过键来查询对应的值。
    • 该类支持拷贝构造、赋值运算符重载,确保深拷贝 m_section_data,同时重载了 [] 操作符,方便通过键直接查询对应值。
  2. ConfigMgr

    • ConfigMgr 类用于管理整个配置文件。它使用 std::map<std::string, SectionInfo> 来存储多个 section,每个 section 名称(字符串类型)与 SectionInfo 对象相关联。
    • ConfigMgr 是一个管理类,负责处理多个 SectionInfo 对象,也就是整个配置文件的结构。通过重载的 [] 操作符,用户可以根据 section 名字直接获取对应的 SectionInfo 对象,从而进一步访问该 section 内的键值对。

C++实现

  • SectionInfo类的实现
struct SectionInfo
{
    std::map<std::string, std::string> m_section_data;
    SectionInfo(){}
    ~SectionInfo(){}

    SectionInfo(const SectionInfo& rhs)
    {
        m_section_data = rhs.m_section_data;
    }

    SectionInfo& operator=(const SectionInfo& rhs)
    {
        if(&rhs==this)  return *this;
        this->m_section_data = rhs.m_section_data;
        return *this;
    }

    std::string operator[](const std::string& key)
    {
        if(m_section_data.find(key)==m_section_data.end())
        {
            return std::string("");
        }
        return m_section_data[key];
    }
};
  • ConfigMgr类的声明
class ConfigMgr {
public:
    ConfigMgr();
    ConfigMgr(const ConfigMgr& rhs);
    ~ConfigMgr();

    SectionInfo operator[](const std::string& section_name);
    ConfigMgr& operator=(const ConfigMgr& rhs);

private:
    // 存储section和key-value对的map
    std::map<std::string, SectionInfo> m_config_map;
};
  • ConfigMgr的定义
// 构造函数:加载并解析配置文件
ConfigMgr::ConfigMgr()
{
    // 获取当前路径, 当前路径为可执行程序所在路径
    boost::filesystem::path current_path = boost::filesystem::current_path();
    // 构建config.ini文件的完整路径
    boost::filesystem::path config_path = current_path / "config.ini";
    std::cout << "Config path: " << config_path << std::endl;

    // 使用Boost.PropertyTree来读取INI文件
    boost::property_tree::ptree pt;
    boost::property_tree::read_ini(config_path.string(), pt);  // 读取INI文件并存储在ptree中

    // 遍历INI文件中的所有section
    for (const auto& section_pair : pt) {
        const std::string& section_name = section_pair.first;  // 获取section名称
        const boost::property_tree::ptree& section_tree = section_pair.second;  // 获取该section的树结构
        
        // 存储每个section的键值对
        std::map<std::string, std::string> section_config;
        
        // 遍历section中的所有key-value对
        for (const auto& key_value_pair : section_tree) {
            const std::string& key = key_value_pair.first;  // 获取键名
            const std::string& value = key_value_pair.second.get_value<std::string>();  // 获取键对应的值
            section_config[key] = value;  // 将键值对存入section_config
        }

        // 将该section的键值对存入SectionInfo对象中
        SectionInfo sectionInfo;
        sectionInfo.m_section_data = section_config;

        // 将SectionInfo对象保存到配置映射中,键为section名称
        m_config_map[section_name] = sectionInfo;
    }

    // 输出所有的section及其包含的键值对,便于检查
    for (const auto& section_entry : m_config_map) {
        const std::string& section_name = section_entry.first;  // 获取section名称
        SectionInfo section_config = section_entry.second;  // 获取SectionInfo对象
        std::cout << "[" << section_name << "]" << std::endl;  // 输出section名称
        for (const auto& key_value_pair : section_config.m_section_data) {
            std::cout << key_value_pair.first << "=" << key_value_pair.second << std::endl;
        }
    }
}

ConfigMgr::ConfigMgr(const ConfigMgr& rhs)
{
    m_config_map = rhs.m_config_map;
}

ConfigMgr::~ConfigMgr()
{
}

SectionInfo ConfigMgr::operator[](const std::string& section_name)
{
    if(m_config_map.find(section_name) == m_config_map.end())
    {
        return SectionInfo();
    }

    return m_config_map[section_name];
}

ConfigMgr& ConfigMgr::operator=(const ConfigMgr& rhs)
{
    if(&rhs == this)    return *this;
    this->m_config_map = rhs.m_config_map;
    return *this;
}
  • 在main函数中
#include "ConfigMgr.h"

int main()
{
    ConfigMgr config;
    std::cout << "----------- main test -----------" << std::endl;
    std::cout <<"host:" << config["database"]["host"] << std::endl;
    std::cout <<"file" << config["logging"]["file"] << std::endl;
    return 0;
}
  • 输出结果,正确

image-20240910215516896

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值