2017-04-18 56 views
0

我有這樣的一個配置文件中提取值,其中properties1可以有1個或多個值:如何使用升壓C++屬性映射從配置文件

[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); 

我與屬性映射的嘗試,但它似乎沒有工作...我想使每個對象中的節點,然後邊向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); 
+1

我不知道很多關於property_map。對於解析INI文件,我通常使用'boost :: property_tree',參見[這個答案](http://stackoverflow.com/a/6176389/7571258)。 – zett42

回答

2

你已經得到了庫錯誤。屬性映射是一個通用的「lense」類庫,用於基於某種輸入參數訪問(讀/寫)屬性。

爲了增加對損傷的侮辱,代碼示例是(顯然是)來自Boost圖形的,這是Boost Propery Map出生的母庫。

現在,你想要Boost Property Tree。樣品是很容易找到的,另外還有一個:

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') 
相關問題