2013-03-04 105 views
17

JSON文件我有一個這樣的文件:閱讀與升壓

[data.json]

{ 
    "electron": { 
     "pos": [0,0,0], 
     "vel": [0,0,0] 
    }, 

    "proton": { 
     "pos": [1,0,0], 
     "vel": [0,0.1,0] 
    }, 

    "proton": { 
     "pos": [-1,0,0], 
     "vel": [0,-0.1,-0.1] 
    } 
} 

如何創建粒子從解析該文件的向量。據我瞭解,我需要使用boost讀取文件,並將字符串(行)讀入向量,然後解析向量的內容。

類粒子是這樣的:

class Particle 
{ 

    private: 
    particle_type mtype; // particle_type is an enum 
    vector<double> mPos; 
    vector<double> mVel; 
}; 

爲的get/set其它方法在課堂上省略。

基本上我想幫助創建一個vector<Particle>與正確的位置和速度數據和particle_type數據解析到它。提前致謝。

碼主:

int main(){ 

    boost::property_tree::ptree pt; 
    boost::property_tree::read_json("data.json", pt); 
} 
+3

你看看升壓JSON解析器:http://www.boost.org /doc/libs/1_53_0/doc/html/boost_propertytree/parsers.html#boost_propertytree.parsers.json_parser? – 2013-03-04 16:55:29

+0

是的,但我無法繞過它... – user3728501 2013-03-04 16:56:12

+1

而這個答案http://stackoverflow.com/a/12735086/667433沒有幫助嗎? – 2013-03-04 16:57:24

回答

5

您可以用下面的代碼迭代:

boost::property_tree::basic_ptree<std::string,std::string>::const_iterator iter = pt.begin(),iterEnd = pt.end(); 
for(;iter != iterEnd;++iter) 
{ 
    iter->first; // Your key, at this level it will be "electron", "proton", "proton" 
    iter->second; // The object at each step {"pos": [0,0,0], "vel": [0,0,0]}, etc. 
} 

希望它可以幫助

+0

伊特有第一個和第二個......但他們是什麼?還有三分之一嗎? – user3728501 2013-03-04 17:06:37

+1

@EdwardBird:'iter'是一對,所以沒有第三個。 'v.first'是一個持有父節點的'std :: string','v.second'是'boost :: property_tree :: ptree',它可以用來解析對象的字段。您可能需要遞歸遍歷樹來獲取所有值,具體取決於值的埋藏程度。 – 2013-03-04 17:18:36

+0

啊好吧謝謝,這有幫助。 – user3728501 2013-03-04 18:04:30

23

我修改你的JSON一點。稍微未經測試的代碼。

{ 
    "particles": [ 
     { 
      "electron": { 
       "pos": [ 
        0, 
        0, 
        0 
       ], 
       "vel": [ 
        0, 
        0, 
        0 
       ] 
      }, 
      "proton": { 
       "pos": [ 
        -1, 
        0, 
        0 
       ], 
       "vel": [ 
        0, 
        -0.1, 
        -0.1 
       ] 
      } 
     } 
    ] 
} 

...

#ifdef _MSC_VER 
#include <boost/config/compiler/visualc.hpp> 
#endif 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/json_parser.hpp> 
#include <boost/foreach.hpp> 
#include <cassert> 
#include <exception> 
#include <iostream> 
#include <sstream> 
#include <string> 

int main() 
{ 
    try 
    { 
     std::stringstream ss; 
     // send your JSON above to the parser below, but populate ss first 


     boost::property_tree::ptree pt; 
     boost::property_tree::read_json(ss, pt); 

     BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("particles.electron")) 
     { 
      assert(v.first.empty()); // array elements have no names 
      std::cout << v.second.data() << std::endl; 
      // etc 
     } 
     return EXIT_SUCCESS; 
    } 
    catch (std::exception const& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 
    return EXIT_FAILURE; 
} 

修改,你認爲合適。

打印整個樹來查看正在讀取的內容。這有助於調試。

void print(boost::property_tree::ptree const& pt) 
{ 
    using boost::property_tree::ptree; 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) { 
     std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl; 
     print(it->second); 
    } 
} 
+0

我沒有覺得這有幫助 - '沒有這樣的節點(particles.electron)'。對於任何人誰不熟悉,'的std :: stringstream的ss'應該被刪除,而'提振:: property_tree :: read_json(SS,PT);用''替代的boost :: property_tree :: read_json(<您的路徑並FILE NAME HERE>,pt);' – user3728501 2013-03-04 21:58:06

+0

@EdwardBird:'read_json'需要一個流,它在boost的文檔中。您不能正確填充它。 – 2013-03-04 22:21:26

+0

你有什麼建議。 (請參閱我的編輯主)編輯:我沒有什麼可以添加在主...你有什麼建議? – user3728501 2013-03-04 22:22:55

2

只是糾正問題與上面的答案,但我不能得到正確格式化的評論:

#ifdef _MSC_VER 
#include <boost/config/compiler/visualc.hpp> 
#endif 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/json_parser.hpp> 
#include <boost/foreach.hpp> 
#include <cassert> 
#include <exception> 
#include <iostream> 
#include <sstream> 
#include <string> 

void print(boost::property_tree::ptree const& pt) 
{ 
    using boost::property_tree::ptree; 
    ptree::const_iterator end = pt.end(); 
    for (ptree::const_iterator it = pt.begin(); it != end; ++it) { 
     std::cout << it->first << ": " << it->second.get_value<std::string>() << std::endl; 
     print(it->second); 
    } 
} 

int main() 
{ 
    try 
    { 
     std::stringstream ss; 
     // send your JSON above to the parser below, but populate ss first 

     ss << "{ \"particles\": [ { \"electron\": { \"pos\": [ 0, 0, 0 ], \"vel\": [ 0, 0, 0 ] }, \"proton\": { \"pos\": [ -1, 0, 0 ], \"vel\": [ 0, -0.1, -0.1 ] } } ]}"; 


     boost::property_tree::ptree pt; 
     boost::property_tree::read_json(ss, pt); 

     BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("particles")) 
     { 
      assert(v.first.empty()); // array elements have no names 
      print(v.second); 
     } 
     return EXIT_SUCCESS; 
    } 
    catch (std::exception const& e) 
    { 
     std::cerr << e.what() << std::endl; 
    } 
    return EXIT_FAILURE; 
} 
+0

還,程序沒有運行錯誤是「‘打印’在此範圍內沒有宣佈」我試圖去改變它給printf,但沒有奏效。 – 2017-12-05 14:00:28

+0

打印定義在使用ptree類型不打印的主函數下面。也許你忘了複製上面的全部內容。我現在沒有電腦可以重新測試。 – Jim 2017-12-05 17:30:30

+0

也許打印需要粘貼在主要上方 – Jim 2017-12-05 17:31:15