基于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
相关产品推荐
相关产品推荐

