【问题标题】:How to use boost c++ property map to extract values from config file如何使用 boost c++ 属性映射从配置文件中提取值
【发布时间】:2017-09-14 19:02:18
【问题描述】:

我有一个这样的配置文件,其中 properties1 可以有 1 个或多个值:

[OBJECT]
properties1=val1, val2, val3
porperty2=Blah
property3=Blah
property4=Blah
porperty5=Bla bla bla

[OBJECT]
properties1=val1
porperty2=Blah
property3=Blah
property4=Blah
porperty5=Bla bla bla

我正在使用boost::program_options 解析它。但是它不能正常工作,因为例如properties1 被存储到一个向量中,因此不可能获得每个 OBJECT 及其属性之间的映射。所以我认为boost::property_map 可能是一个很好的解决方案。这是当前的解决方案:

  namespace po = boost::program_options;

  std::vector<std::string> properties1_all;
  std::vector<std::string> property2_all;
  std::vector<std::string> property3_all;
  std::vector<std::string> property4_all;
  std::vector<std::string> property5_all;

  po::options_description desc;
  desc.add_options()
      ("OBJECT.properties1",
      po::value<std::vector<std::string> >(&properties1_all))
      ("OBJECT.property2",
      po::value<std::vector<std::string> >(&property2_all))
      ("OBJECT.property3",
      po::value<std::vector<std::string> >(&property3_all))
      ("OBJECT.property4",
      po::value<std::vector<std::string> >(&property4_all))
      ("OBJECT.property5",
      po::value<std::vector<std::string> >(&property5_all));

  po::variables_map vm;
  std::ifstream settings_file("config.ini", std::ifstream::in);
  po::store(po::parse_config_file(settings_file, desc), vm);
  settings_file.close();
  po::notify(vm);

我尝试使用属性映射,但它似乎不起作用......我认为让每个 OBJECT 成为一个节点,然后将其作为其属性的 5 个顶点的边,将是一个很好的解决方案:

 typedef adjacency_list<vecS, vecS, bidirectionalS, 
    no_property, property<edge_index_t, std::size_t> > Graph;

  const int num_vertices = 5;
  Graph G(num_vertices);

  int propertyarray[] = { 1, 2, 3, 4, 5 };
  int objectarray[] = { 1, 2, 3 };

  // Add edges to the graph, and assign each edge an ID number.
  add_edge(0, 1, 0, G);
  // ...

  typedef graph_traits<Graph>::edge_descriptor Edge;
  typedef property_map<Graph, edge_index_t>::type EdgeID_Map;
  EdgeID_Map edge_id = get(edge_index, G);

【问题讨论】:

  • 我对property_map了解不多。对于解析 INI 文件,我通常使用boost::property_tree,参见this answer

标签: c++ boost


【解决方案1】:

你弄错了库。 Property Map 是一个通用的“lense”类库,用于根据某种输入参数访问(读/写)属性。

为了雪上加霜,代码示例(显然?)来自 Boost Graph,这是 Boost Propery Map 诞生的母库。

现在,您需要 Boost 属性树。这些样本很容易找到,这里还有一个:

Live On Coliru

#include <iostream>
#include <map>
#include <boost/property_tree/ini_parser.hpp>

static std::string const sample = R"(
[BLA]
properties1=val1, val2, val3
property2=Blah
property3=Blah
property4=Blah
property5=Bla bla bla

[BLO]
properties1=val1
property2=Blah
property3=Blah
property4=Blah
property5=Bla bla bla
)";

struct Object {
    std::string properties1, property2, property3, property4, property5;
};

using boost::property_tree::ptree;

void read(ptree const& pt, std::string& s) {
    s = pt.get_value(s);
}

void read(ptree const& pt, Object& object) {
    read(pt.get_child("properties1"), object.properties1);
    read(pt.get_child("property2"), object.property2);
    read(pt.get_child("property3"), object.property3);
    read(pt.get_child("property4"), object.property4);
    read(pt.get_child("property5"), object.property5);
}

template <typename T>
T read_as(ptree const& pt) {
    T v;
    read(pt, v);
    return v;
}

int main() {

    std::istringstream iss(sample);
    boost::property_tree::ptree config;
    read_ini(iss, config);

    std::map<std::string, Object> parsed;

    for (auto& section : config) {
        parsed[section.first] = read_as<Object>(section.second);
    }

    for (auto& object : parsed) {
        std::cout << "Parsed object named " << object.first << " (e.g. property5 is '" << object.second.property5 << "')\n";
    }
}

印刷:

Parsed object named BLA (e.g. property5 is 'Bla bla bla')
Parsed object named BLO (e.g. property5 is 'Bla bla bla')

【讨论】:

    猜你喜欢
    • 2021-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-19
    • 2021-07-01
    • 2014-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多