You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Boost库读写INI文件:遇未知选项终止并保存配置

用Boost库实现INI配置的严格读取与保存

我来帮你梳理下用Boost库实现这个需求的完整方案,结合你给出的代码片段,咱们一步步来:

需求回顾

  • 从目标INI文件读取配置选项
  • 若文件中存在未知选项,立即终止程序
  • 将读取到的合法配置保存至另一个指定的INI文件

1. 基于Boost.Program_options的严格读取实现

Boost.Program_options默认允许配置文件中存在未定义的选项,要实现"未知选项即终止"的逻辑,需要在解析时设置allow_unregistered(false)。下面是完善后的读取代码:

#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

// 定义配置结构体
struct Config {
    int nx;
    // 可按需添加更多配置项
};

int main() {
    Config p;
    std::string input_ini = "input.ini";
    std::string output_ini = "output.ini";

    try {
        // 定义允许的配置选项
        po::options_description inifile_options("Allowed options");
        inifile_options.add_options()
            ("ops1.i0", po::value<int>(&p.nx)->default_value(1), "test integer");

        po::variables_map vm;
        // 解析配置文件,设置不允许未注册选项(第三个参数为false)
        po::store(po::parse_config_file(input_ini.c_str(), inifile_options, false), vm);
        po::notify(vm); // 触发值的赋值与参数校验

        std::cout << "Successfully read config: ops1.i0 = " << p.nx << std::endl;
    } catch (const std::exception& e) {
        std::cerr << "Error reading config: " << e.what() << std::endl;
        return 1; // 遇到未知选项或其他错误,直接终止程序
    }

    // 后续的保存逻辑...
    return 0;
}

关键说明:

  • parse_config_file的第三个参数设为false,表示拒绝未注册的选项,一旦遇到就会抛出unknown_option异常
  • po::notify(vm)会触发配置值的赋值,同时校验是否有必填项未设置(若有定义必填项的话)

2. 将配置保存到新INI文件

Boost.Program_options没有提供直接写入INI的API,我们可以自己实现一个简单的写入逻辑,既可以硬编码键值对(适合配置项少的场景),也可以基于options_description动态生成内容(适合配置项多的场景)。

方式一:硬编码写入(简单直接)

// 新增保存配置的函数
void save_config(const Config& p, const std::string& filename) {
    std::ofstream outfile(filename);
    if (!outfile.is_open()) {
        std::cerr << "Failed to open output file: " << filename << std::endl;
        exit(1);
    }

    // 按INI格式写入配置段落与键值对
    outfile << "[ops1]" << std::endl;
    outfile << "i0 = " << p.nx << std::endl;

    outfile.close();
    std::cout << "Config saved to " << filename << std::endl;
}

// 在main函数的读取成功后调用
save_config(p, output_ini);

方式二:基于选项定义动态写入(灵活扩展)

如果你的配置项较多,不想硬编码键名,可以用这个方法:

void save_config_from_options(const po::options_description& desc, const po::variables_map& vm, const std::string& filename) {
    std::ofstream outfile(filename);
    if (!outfile.is_open()) {
        std::cerr << "Failed to open output file: " << filename << std::endl;
        exit(1);
    }

    // 遍历所有选项组,生成INI段落
    for (const auto& option_group : desc.groups()) {
        if (!option_group.name.empty()) {
            outfile << "[" << option_group.name << "]" << std::endl;
        }
        // 遍历组内每个选项,写入对应键值对
        for (const auto& option : option_group.options) {
            const std::string& full_key = option->long_name();
            if (vm.count(full_key)) {
                // 提取段落内的键名(比如从"ops1.i0"提取"i0")
                std::string key = full_key.substr(full_key.find('.') + 1);
                // 这里以int类型为例,可扩展string、bool等类型的处理
                if (auto* value = boost::any_cast<int>(&vm[full_key].value())) {
                    outfile << key << " = " << *value << std::endl;
                }
            }
        }
        outfile << std::endl;
    }
    outfile.close();
}

调用时只需传入定义好的选项描述和变量映射:

save_config_from_options(inifile_options, vm, output_ini);

完整示例代码

把读取和保存逻辑整合起来,完整代码如下:

#include <iostream>
#include <fstream>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

struct Config {
    int nx;
};

void save_config(const Config& p, const std::string& filename) {
    std::ofstream outfile(filename);
    if (!outfile.is_open()) {
        std::cerr << "Failed to open output file: " << filename << std::endl;
        exit(1);
    }

    outfile << "[ops1]" << std::endl;
    outfile << "i0 = " << p.nx << std::endl;

    outfile.close();
    std::cout << "Config saved to " << filename << std::endl;
}

int main() {
    Config p;
    std::string input_ini = "input.ini";
    std::string output_ini = "output.ini";

    try {
        po::options_description inifile_options("Allowed options");
        inifile_options.add_options()
            ("ops1.i0", po::value<int>(&p.nx)->default_value(1), "test integer");

        po::variables_map vm;
        po::store(po::parse_config_file(input_ini.c_str(), inifile_options, false), vm);
        po::notify(vm);

        std::cout << "Successfully read config: ops1.i0 = " << p.nx << std::endl;
        save_config(p, output_ini);
    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}

编译时需要链接Boost库,比如用g++的命令:

g++ -std=c++11 your_code.cpp -o config_tool -lboost_program_options

内容的提问来源于stack exchange,提问作者Oscillon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:15:49