c++ - 使用 boost::{program_options,property_tree} 读取/写入 inifiles

标签 c++ boost boost-program-options boost-propertytree

利用Boost,我想

  1. 从 ini 文件中读取选项,如果在 ini 文件中遇到未知选项则中止
  2. 稍后将它们保存在另一个 ini 文件中。

第一部分可以使用 boost::program_options 完成:

try{
    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(pthfnini, inifile_options), vm);
    po::notify(vm);
}   
catch(exception& e){
    cerr << "error: " << e.what() << "\n";
    errorflag=1;
}

据我所知,使用 boost::program_options 不可能编写 inifile,但 boost::property_tree 可以:

pt::ptree iniPropTree;
pt::ini_parser::write_ini("./used0.ini",iniPropTree);

现在的问题是如何将 po::variables_map 中存储的数据转换为 pt::ptree?

阅读 boost 文档给我的印象是这是不可能的。以下是唯一可行的方法吗?

iniPropTree.put<int>("ops1.i0",vm["ops1.i0"].as<int>();

根据我的口味,它引入了相当多的冗余。但是,从头开始将数据读入属性树似乎不支持检查未定义/拼写错误的选项。

或者,是否可以迭代variables_map的内容并以某种方式推断每个元素相应的数据类型?

完整代码在这里:

/*
 * g++ iniOps_test.cpp -Wall -std=c++11 -O3 -lboost_system -lboost_program_options -o iniOps_test.exe
 * 
 */

// C++11 & Boost libraries
#include <boost/program_options.hpp>            // po::options_description, po::variables_map, ...
#include <boost/property_tree/ptree.hpp>        // pt::ptree
#include <boost/property_tree/ini_parser.hpp>   // write_ini()
#include <iostream>                             // cout
#include <fstream>                              // ofstream, ifstream


// namespaces
namespace po = boost::program_options;
namespace pt = boost::property_tree;
using namespace std;


struct params{
    std::string inipthfn;
    int i0;
};


void read_inifile(params &p, po::variables_map &vm){

    // initialize variables
    int errorflag=0;
    std::ifstream pthfnini("./testini.ini");
    po::options_description inifile_options("Allowed inifile options");

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

        ;
        po::store(po::parse_config_file(pthfnini, inifile_options), vm);
        po::notify(vm);
    }
    catch(exception& e){
        cerr << "error: " << e.what() << "\n";
        errorflag=1;
    }

    pthfnini.close();
    if(errorflag){ std::cout<<"--- program shutdown due to error in read_inifile ---"<<std::endl; exit(1); }
}


int main(){

    params p;
    po::variables_map vm;
    pt::ptree iniPropTree;

    read_inifile(p,vm);                                     // get options from inifile

    // ??? conversion from vm -> pt ???

    pt::ini_parser::write_ini("./used0.ini",iniPropTree);   // save options to used.ini
    cout << p.i0 << endl;

    return 0;
}

ini文件“testini.ini”的内容是:

[ops1]
i0=2

最佳答案

这里有一个概念问题。

命令行参数本质上是文本的。

变量映射中的值不是。使用的类型在值语义(选项描述的一部分)中配置。

如果您的所有选项都具有相同的类型,您可以“作弊”并对转换进行硬编码:

pt::ptree to_ptree(po::variables_map const& vm) {
    pt::ptree tree;
    for (auto& v : vm) {
        if (!v.second.empty() && !v.second.defaulted())
            tree.put(v.first, v.second.as<int>());
    }

    return tree;
}

这节省了:

[ops1]
i0=1

如果您需要更大的灵活性,您至少需要访问选项描述。这不是该库的预期用途,您可能很快就会遇到未记录的实现部分。

关于c++ - 使用 boost::{program_options,property_tree} 读取/写入 inifiles,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50233440/

相关文章:

c++ - boost::program_options - 如何处理 INI 文件中具有相同名称的多个部分

c++ - 如何从 Win32 C++ 应用程序输出到父控制台窗口?

C++ 内存分配 howto

python - 用 Python Boost 包装 C++ operator()

python - 在一个共享对象中 boost python 多个模块

c++ - Boost 程序选项和 "one of"关系

c++ - 跨线程信号槽,如何发送char *

android - Android 上的 Qt 有一些 WebKit 替代品吗?

c++ - 如何链接到现有的 boost python 模块

c++ - 如何使用 CMake 在 macOS 上使用和链接 boost?