2013-03-04 18 views
17

Ho un file in questo modo:lettura di file JSON con boost

[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] 
    } 
} 

Come faccio a creare un vettore di particelle da analisi di questo file. A quanto ho capito, ho bisogno di leggere il file usando boost e leggere le stringhe (linee) in un vettore, e quindi analizzare il contenuto del vettore.

La particella classe è qualcosa di simile:

class Particle 
{ 

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

Altri metodi per get/set sono stati omessi nella classe.

Fondamentalmente mi piacerebbe aiutare a creare un vector<Particle> con i dati di posizione e velocità e particle_type corretti in esso. Grazie in anticipo.

Codice in principale:

int main(){ 

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

Hai avuto uno sguardo al Boost JSON parser: http://www.boost.org /doc/libs/1_53_0/doc/html/boost_propertytree/parsers.html#boost_propertytree.parsers.json_parser? –

+0

Sì, ma non riesco a capirlo ... – user3728501

+1

E questa risposta http://stackoverflow.com/a/12735086/667433 non ha aiutato nessuno dei due? –

risposta

5

È possibile scorrere con il seguente codice:

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. 
} 

Speranza che aiuta

+0

Iter ha un primo e un secondo ... Ma cosa sono? C'è anche un terzo? – user3728501

+1

@EdwardBird: 'iter' è una coppia, quindi non c'è un terzo. 'v.first' è un' std :: string' che contiene il nodo genitore e 'v.second' è un' boost :: property_tree :: ptree', che può essere usato per analizzare i campi dell'oggetto. Potrebbe essere necessario attraversare ricorsivamente l'albero per ottenere tutti i valori in base alla profondità dei tuoi sepolti. –

+0

Ah ok grazie, questo aiuta. – user3728501

23

ho modificato il tuo JSON un po '. Codice leggermente non testato

{ 
    "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; 
} 

Modificare come si vede in forma.

Stampa l'intero albero per vedere cosa viene letto. Questo aiuta a fare il debug.

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

Non ho trovato utile questo - 'No tale nodo (particles.elettrone)'.Per chi non lo conoscesse, 'std :: stringstream ss' dovrebbe essere rimosso, e' boost :: property_tree :: read_json (ss, pt); 'sostituito con' boost :: property_tree :: read_json (, pt); ' – user3728501

+0

@EdwardBird:' read_json' prende uno stream, è nella documentazione di boost. Non è necessario averlo compilato correttamente. –

+0

cosa suggerisci. (Vedi la mia modifica in main) EDIT: Non c'è niente da aggiungere al main ... Che cosa suggerisci? – user3728501

2

Basta correggere problemi con la risposta di cui sopra, ma non potrei ottenere la formattazione corretta nei commenti:

#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

ancora, il programma non è in esecuzione l'errore è" 'print' non è stato dichiarato in questo ambito "Ho provato a cambiarlo in printf ma non ha funzionato. La stampa –

+0

viene definita sotto la funzione principale utilizzando i tipi di ptree non stampati. Forse hai dimenticato di copiare l'intero contenuto sopra. Non ho un computer con cui ripetere il test adesso. – Jim

+0

Forse la stampa deve essere incollata sopra il main – Jim