• 基于C++的配置文件解析器/编码器——toml库


      在平常的软件开发过程中,配置文件是重要的一环,使用配置文件在软件开发过程中具有以下好处和必要性:

    • 灵活性:配置文件允许在不修改代码的情况下更改应用程序的行为,通过修改配置文件,可以调整应用程序的参数、设置和选项,以满足不同的需求和环境。
    • 可维护性:将配置信息从代码中分离出来,使得维护和管理变得更加容易,当需要修改配置时,只需修改配置文件,而不需要重新编译和部署整个应用程序。
    • 可扩展性:配置文件可以用于支持应用程序的扩展。通过添加新的配置项,可以轻松地引入新的功能或模块,而无需修改现有的代码。
    • 跨环境部署:使用配置文件可以轻松地在不同的环境中部署应用程序,例如开发、测试和生产环境,通过切换不同的配置文件,可以适应不同环境的需求。
      总之,配置文件在软件开发中起到了关键的作用,它们提供了一种灵活、可维护和可扩展的方式来管理应用程序的行为和设置。

      虽然写配置文件本身是一个简单的事情,但很容易出错,且容易因为规范不一导致解析出错,自从使用了TOML库,发现是真香!
    在这里插入图片描述

    1.关于toml

      toml11是一个C++的库,用于解析和生成 TOML(Tom’s Obvious, Minimal Language)格式的配置文件。TOML是一种易于阅读和编写的配置文件格式,被广泛用于各种应用程序的配置文件中。主要作用是提供了一种简单、高效的方式来读取和写入TOML格式的配置文件。

    源码:
    https://github.com/marzer/tomlplusplus
    https://github.com/ToruNiina/toml11

    https://gitee.com/boss-dog/tomlplusplus
    https://gitee.com/boss-dog/toml11

      toml11和tomlplusplus都是C++的库,用于解析和生成TOML格式的配置文件。
      toml11是一个轻量级的TOML库,可以直接包含在项目中使用,无需额外的依赖,代码量较小,功能相对较少,但足以满足大多数简单的TOML文件解析和生成需求。
      tomlplusplus是一个更为全面和功能丰富的TOML库,它是基于toml11的基础上进行扩展和改进的,支持更多的TOML语法特性,提供了更灵活的配置选项和更强大的错误处理机制。
      总的来说,toml11适用于简单的TOML文件解析和生成需求,它轻量、易用、快速。而tomlplusplus则适用于更复杂的TOML文件操作,提供了更多的功能和选项,并具有更好的性能。选择使用哪个库取决于具体的需求和项目的规模。

    1.1 安装toml

    • 1.从toml11的仓库下载源代码
    git clone https://gitee.com/boss-dog/toml11.git
    
    • 1
    • 2.将下载的源代码放置在项目目录中的合适位置。

    • 3.在CMakeLists.txt文件中添加以下内容,以引入toml11库:

    # 设置toml11库的路径
    set(TOML11_INCLUDE_DIR /path/to/toml11)
    
    # 添加toml11库的头文件路径
    include_directories(${TOML11_INCLUDE_DIR})
    
    # 添加toml11库的源文件
    add_library(toml11 INTERFACE)
    target_include_directories(toml11 INTERFACE ${TOML11_INCLUDE_DIR})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    请确保将/path/to/toml11替换为实际的toml11库的路径。

    • 在项目中可以使用#include "toml.hpp"来包含toml11库的头文件,并使用toml::前缀来访问toml11库的功能

    2.示例:使用toml库编写对配置文件的解析

    dog_roster.conf

    num_dog = 3
    version = '1.1.2'
    
    [[Zhou]]
    name = 'BuDing'
    adopted = true
    age = 4
    weight = 15.6
    height = 30.0
    
        [Zhou.options]
        pose = [0.1,0.2,0.3]
    
    
    [[Zhou]]
    name = 'DuoDuo'
    adopted = true
    age = 3.5
    weight = 15.6
    height = 29.8
    
        [Zhou.options]
        pose = [1.1,1.2,1.3]
    
    [[Zhou]]
    name = 'PaoPao'
    adopted = false
    age = 6
    weight = 28.2
    height = 50.1
    
        [Zhou.options]
        pose = [0.01,0.02,0.03]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    CMakeLists.txt

    cmake_minimum_required(VERSION 3.16)
    project(MyDemo)
    
    # 设置C++标准
    set(CMAKE_CXX_STANDARD 17)
    
    # 设置toml11库的路径
    set(TOML11_INCLUDE_DIR toml11)
    
    # 添加toml11库的头文件路径
    include_directories(${TOML11_INCLUDE_DIR})
    
    # 添加可执行文件
    add_executable(test_toml
        test_toml.cpp
    )
    
    # 添加toml11库的源文件
    add_library(toml11 INTERFACE)
    target_include_directories(test_toml INTERFACE ${TOML11_INCLUDE_DIR})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    test_toml.cpp

    #include 
    #include "toml.hpp"
    
    int main()
    {
        // 解析配置文件
        std::ifstream config_file("../dog_roster.conf");
    
        if (!config_file.is_open()) {
            std::cerr << "Failed to open config file!" << std::endl;
            return -1;
        }
        const auto data = toml::parse(config_file);
    
        // 获取num_dog和version的值
        const int num_dog = toml::find<int>(data, "num_dog");
        const std::string version = toml::find<std::string>(data, "version");
    
        std::cout << "num_dog: " << num_dog << std::endl;
        std::cout << "version: " << version << std::endl;
    
        try {
            // 遍历每个狗的信息
            const auto &dogs = toml::find(data, "Zhou");
            for (const auto &dog : dogs.as_array()) {
                const std::string name = toml::find<std::string>(dog, "name");
                const bool adopted = toml::find<bool>(dog, "adopted");
    
                int age = -1;
                if (dog.at("age").is_integer()) {
                    age = toml::find<int>(dog, "age");
                } else if (dog.at("age").is_floating()) {
                    age = toml::find<double>(dog, "age");
                }
    
                const double weight = toml::find<double>(dog, "weight");
                const double height = toml::find<double>(dog, "height");
    
                std::cout << "name: " << name << std::endl;
                std::cout << "adopted: " << (adopted ? "true" : "false")
                          << std::endl;
                std::cout << "age: " << age << std::endl;
                std::cout << "weight: " << weight << std::endl;
                std::cout << "height: " << height << std::endl;
    
                // 获取pose选项的值
                const auto &options = toml::find(dog, "options");
                const auto pose = toml::find<std::vector<double>>(options, "pose");
    
                std::cout << "pose: [";
                for (const auto &p : pose) {
                    std::cout << p << ", ";
                }
                std::cout << "]" << std::endl;
            }
        } catch (const toml::syntax_error &e) {
            std::cerr << "Syntax error in configuration file: " << e.what()
                      << std::endl;
        } catch (const std::exception &e) {
            std::cerr << "Error occurred: " << e.what() << std::endl;
        }
    
        std::cout << "Finished!" << std::endl;
        return 0;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    在这里插入图片描述

  • 相关阅读:
    ELK日志分析系统+ELFK(Filebeat)
    vue3 ts中常用的类型推断
    MySQL5.7.35的安装
    redis未授权访问漏洞的利用
    c语言练习86:移除元素
    C/C++图的最小生成树和最短路径的实践
    Linux用户管理常用命令及对应配置文件
    华为机试真题 Java 实现【矩阵最大值】
    【正点原子FPGA连载】第二十三章 DDS信号发生器实验摘自【正点原子】DFZU2EG/4EV MPSoC 之FPGA开发指南V1.0
    不平衡之钥: 重加权法知几何
  • 原文地址:https://blog.csdn.net/qq_45445740/article/details/136518126