【问题标题】:Reading json file with boost用boost读取json文件
【发布时间】:2013-03-04 16:53:03
【问题描述】:

我有一个这样的文件:

[数据.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&lt;Particle&gt;,其中包含正确的位置和速度数据以及解析到其中的particle_type 数据。提前致谢。

主代码:

int main(){

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

【问题讨论】:

标签: c++ json


【解决方案1】:

我稍微修改了你的 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);
    }
}

【讨论】:

  • 我没有发现这有帮助 - No such node (particles.electron)。不熟悉的朋友可以把std::stringstream ss去掉,把boost::property_tree::read_json(ss, pt);换成boost::property_tree::read_json(&lt;YOUR PATH TO AND FILE NAME HERE&gt;, pt);
  • @EdwardBird: read_json 需要一个流,它在 boost 的文档中。您一定没有正确填充它。
  • 你有什么建议。 (请参阅我在 main 中的编辑) 编辑:我在 main 中没有什么要添加的......你有什么建议?
  • 当我打印树时,一切看起来都很好。
  • 这个例子很有帮助,但是是错误的,在恕我直言之前,确实值得让例子发挥作用。
【解决方案2】:

您可以使用以下代码进行迭代:

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

希望对你有帮助

【讨论】:

  • Iter 有第一个和第二个...但是它们是什么?还有第三个吗?
  • @EdwardBird:iter 是一对,所以没有第三个。 v.first是一个std::string持有父节点,v.second是一个boost::property_tree::ptree,可以用来解析对象的字段。您可能必须递归遍历树才能获取所有值,具体取决于您的值被埋藏的深度。
【解决方案3】:

只是纠正上面答案的问题,但我无法在 cmets 中得到正确的格式:

#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;
}

【讨论】:

  • 仍然,程序没有运行错误是“'print'没有在这个范围内声明”我试图将它更改为printf但它没有工作。
  • print 在 main 函数下方定义,使用 ptree 类型而不是 print。也许您忘记复制上面的全部内容。我现在没有可以重新测试的计算机。
  • 或许打印需要粘贴在main上方
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多