2011-01-03 45 views
17

मुझे संपत्ति के पेड़ को बढ़ावा देने के लिए आ रहा है और देखा कि यह सी ++ प्रोग्रामिंग के लिए बूस्ट libs की एक अच्छी सुविधा है।एक बढ़ावा संपत्ति पेड़ को फिर से कैसे शुरू करें?

ठीक है, मुझे एक संदेह है? Iterators या इसी तरह का उपयोग कर एक संपत्ति पेड़ को फिर से कैसे शुरू करें?

संदर्भ में वहाँ केवल के माध्यम से पेड़ ब्राउज़ कर का एक उदाहरण है:

BOOST_FOREACH 

लेकिन वहाँ कुछ भी नहीं है और अधिक है? एक एसएलएल की तरह कंटेनर की तरह कुछ? यह एक बेहतर समाधान हो सकता है, कोड गुणवत्ता के बारे में बात ....

उत्तर

15

BOOST_FOREACH, शुरू() और अंत()

Your_tree_type::const_iterator end = tree.end(); 
for (your_tree_type::const_iterator it = tree.begin(); it != end; ++it) 
    ... 

और में है कि इटरेटर द्वारा किया जा सकता बार-बार दोहराना के लिए सिर्फ एक सुविधाजनक तरीका है सी ++ 11 यह है:

for (auto it: tree) 
    ... 
+0

मैं दोपहर में परीक्षण करूंगा ... आह, ऐसा नहीं लगता था कि यह इतना आसान था ... मैं आपको जल्द ही बता दूंगा :) – Andry

+0

ठीक है, लेकिन इटेटरेटर .... यह फिर से क्या करता है ???? एक ptree ???? – Andry

+1

पीटीआरई का शीर्ष स्तर, सभी पत्तियों को फिर से करने के लिए आपको इसे फिर से करने की आवश्यकता है –

25

यहां बहुत अधिक प्रयोग के बाद मैं आया हूं। मैं इसे समुदाय में साझा करना चाहता था क्योंकि मुझे वह नहीं मिला जो मैं चाहता था। हर कोई सिर्फ बूस्ट डॉक्स से जवाब पोस्ट करना प्रतीत होता था, जिसे मैंने अपर्याप्त पाया। किसी भी तरह:

#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/json_parser.hpp> 
#include <string> 
#include <iostream> 

using namespace std; 
using boost::property_tree::ptree; 

string indent(int level) { 
    string s; 
    for (int i=0; i<level; i++) s += " "; 
    return s; 
} 

void printTree (ptree &pt, int level) { 
    if (pt.empty()) { 
    cerr << "\""<< pt.data()<< "\""; 
    } 

    else { 
    if (level) cerr << endl; 

    cerr << indent(level) << "{" << endl;  

    for (ptree::iterator pos = pt.begin(); pos != pt.end();) { 
     cerr << indent(level+1) << "\"" << pos->first << "\": "; 

     printTree(pos->second, level + 1); 
     ++pos; 
     if (pos != pt.end()) { 
     cerr << ","; 
     } 
     cerr << endl; 
    } 

    cerr << indent(level) << " }";  
    } 

    return; 
} 

int main(int, char*[]) { 

    // first, make a json file: 
    string tagfile = "testing2.pt"; 
    ptree pt1; 
    pt1.put("object1.type","ASCII"); 
    pt1.put("object2.type","INT64"); 
    pt1.put("object3.type","DOUBLE"); 
    pt1.put("object1.value","one"); 
    pt1.put("object2.value","2"); 
    pt1.put("object3.value","3.0"); 
    write_json(tagfile, pt1); 

    ptree pt; 
    bool success = true; 

    try { 
     read_json(tagfile, pt); 
     printTree(pt, 0); 
     cerr << endl; 
    }catch(const json_parser_error &jpe){ 
     //do error handling 
     success = false 
    } 

    return success; 
} 

यहाँ आउटपुट है:

[email protected] (blockbuster): a.out 
{ 
    "object1": 
    { 
    "type": "ASCII", 
    "value": "one" 
    }, 
    "object2": 
    { 
    "type": "INT64", 
    "value": "2" 
    }, 
    "object3": 
    { 
    "type": "DOUBLE", 
    "value": "3.0" 
    } 
} 
[email protected] (blockbuster): cat testing2.pt 
{ 
    "object1": 
    { 
     "type": "ASCII", 
     "value": "one" 
    }, 
    "object2": 
    { 
     "type": "INT64", 
     "value": "2" 
    }, 
    "object3": 
    { 
     "type": "DOUBLE", 
     "value": "3.0" 
    } 
} 
6

मैं हाल ही में इस मुद्दे में पड़ गए और मेरी जरूरत के लिए अधूरा जवाब मिला, तो मैं इस संक्षिप्त और आकर्षक टुकड़ा के साथ आया था:

using boost::property_tree::ptree; 

void parse_tree(const ptree& pt, std::string key) 
{ 
    std::string nkey; 

    if (!key.empty()) 
    { 
    // The full-key/value pair for this node is 
    // key/pt.data() 
    // So do with it what you need 
    nkey = key + "."; // More work is involved if you use a different path separator 
    } 

    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) 
    { 
    parse_tree(it->second, nkey + it->first); 
    } 
} 

ध्यान देने योग्य है कि रूट नोड को छोड़कर कोई भी नोड डेटा और साथ ही साथ बाल नोड्स भी हो सकता है। if (!key.empty()) बिट रूट रूट नोड के अलावा सभी के लिए डेटा प्राप्त करेगा, हम किसी भी नोड के बच्चों के लूपिंग के लिए पथ बनाने शुरू कर सकते हैं।

आप parse_tree(root_node, "") पर कॉल करके पार्सिंग शुरू करेंगे और निश्चित रूप से आपको इसे करने के लिए इस फ़ंक्शन के अंदर कुछ करने की आवश्यकता है।

यदि आप कुछ पार्सिंग कर रहे हैं जहां आपको पूर्ण पथ की आवश्यकता नहीं है, तो बस nkey चर और उसके संचालन को हटा दें, और बस रिकर्सिव फ़ंक्शन में it->first पास करें।

संबंधित मुद्दे