2

I am trying to parse below JSON file using boost::property_tree.

{
    "pi": 3.141,
    "temp": 3.141,
    "happy": true,
    "name": "Niels",
    "nothing": null,
    "answer": {
        "everything": 42
    },
    "list": [
        1,
        0,
        2
    ],
    "object": {
        "currency": "USD",
        "value": 42.99
    }
}

But for second node 'temp', it is giving an error-

terminate called after throwing an instance of 'boost::wrapexcept<boost::property_tree::ptree_bad_path>'
  what():  No such node (temp)
Aborted (core dumped)
@ubuntu:~/git_

Have written code like below-

std::ifstream file(jsonPath, std::ifstream::binary);
  using json = nlohmann::json;
  namespace pt = boost::property_tree;
  pt::ptree root;
  pt::read_json(jsonPath, root);  // Load the json file in this ptree 
  string valPi = root.get<string>("pi");  
  string valtemp = root.get<string>("temp"); 

2 Answers2

2

Boost Property Tree is not a JSON library.

Why would you (ab)use it, if you already have nlohmann::json included?

Your selector paths may not match the JSON. It's hard to tell because the example you show works correctly:

Live On Coliru

Prints

{
    "pi": "3.141",
    "temp": "3.141",
    "happy": "true",
    "name": "Niels",
    "nothing": "null",
    "answer": {
        "everything": "42"
    },
    "list": [
        "1",
        "0",
        "2"
    ],
    "object": {
        "currency": "USD",
        "value": "42.99"
    }
}
Yay 3.141 and 3.141

No problem.

Note, however, how all type information is lost, which is merely scratching the surface of "limitations" in PropertyTree: https://www.boost.org/doc/libs/1_75_0/doc/html/property_tree/parsers.html#property_tree.parsers.json_parser

Use Boost JSON

Get serious:

#include <boost/json.hpp>
#include <iostream>

int main() {
    auto root = boost::json::parse(R"({
    "pi": 3.141,
    "temp": 3.141,
    "happy": true,
    "name": "Niels",
    "nothing": null,
    "answer": {
        "everything": 42
    },
    "list": [
        1,
        0,
        2
    ],
    "object": {
        "currency": "USD",
        "value": 42.99
    }
})");

    std::cout << root << "\n";
    auto valPi   = root.at("pi").get_double();
    auto valtemp = root.at("temp").get_double();

    std::cout << "Yay " << valPi << " and " << valtemp << "\n";
}

Prints

{"pi":3.141E0,"temp":3.141E0,"happy":true,"name":"Niels","nothing":null,"answer":{"everything":42},"list":
[1,0,2],"object":{"currency":"USD","value":4.299E1}}
Yay 3.141 and 3.141

Using nlohmann::json

Live On Compiler Explorer

#include <nlohmann/json.hpp>
#include <iostream>

int main() {
    auto root = nlohmann::json::parse(R"({
    "pi": 3.141,
    "temp": 3.141,
    "happy": true,
    "name": "Niels",
    "nothing": null,
    "answer": {
        "everything": 42
    },
    "list": [
        1,
        0,
        2
    ],
    "object": {
        "currency": "USD",
        "value": 42.99
    }
})");

    std::cout << root << "\n";
    auto valPi   = root["pi"].get<double>();
    auto valtemp = root["temp"].get<double>();

    std::cout << "Yay " << valPi << " and " << valtemp << "\n";
}

Prints

{"answer":{"everything":42},"happy":true,"list":[1,0,2],"name":"Niels","nothing":null,"object":{"currency"
:"USD","value":42.99},"pi":3.141,"temp":3.141}
Yay 3.141 and 3.141
sehe
  • 374,641
  • 47
  • 450
  • 633
0
  string valPi = root.get<string>("pi");  

This should be changed to :

 std::string valPi =root.get<std::string>(pt::ptree::path_type{"pi"});

if you would like the 2nd level:

 int answer_everything =root.get<int>(pt::ptree::path_type{"answer.everthing"});

or to be fancier using another delimiter :

int answer_everything =root.get<int>(pt::ptree::path_type{"answer\neverthing","\n"});
Quantum
  • 11
  • 2