DEKKER
DEKKER

Reputation: 911

Boost can not find nested nodes in INI file

I have an ini file like this;

[Sensor]
address=69
mode=1
[Sensor.Offsets]
x=65.0
y=-66.3

I am trying to load the values in an struct:

#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/ini_parser.hpp>
#include <spdlog/spdlog.h>

void myFunc() {
    using namespace boost::property_tree;
    ptree pt;
    double x{};
    
    // Read config file
    boost::property_tree::ini_parser::read_ini("config.ini", &pt);    

    try {
        x = pt.get<double>("Sensor.Offsets.x");
    } catch (std::exception& ex) {
        spdlog::error("{}", ex.what());
        exit(-2);
    }
}

I get the error: No such node (Sensor.Offsets.x)

Any idea what is wrong?

Upvotes: 1

Views: 217

Answers (1)

sehe
sehe

Reputation: 393174

You need to "escape" the dot. Dots are special, so your key is interpreted as [Sensor][Offsets][x], not [Sensor.Offsets][x].

You can force it:

auto& so = pt.get_child({"Sensor.Offsets", '#'});
x = so.get<double>("x");

Which is shorthand for

auto& so = pt.get_child(
    boost::property_tree::ptree::path_type{"Sensor.Offsets", '#'});
x = so.get<double>("x");

As you can see it explicitly constructs a path_type argument using a different separator character.

Live Demo

See Compiler Explorer

#include <boost/property_tree/ini_parser.hpp>
#include <fmt/format.h>

int main()
{
    boost::property_tree::ptree pt;

    std::istringstream config_ini("[Sensor]\naddress=69\nmode=1\n[Sensor.Offsets]\nx=65.0\ny=-66.3");
    read_ini(config_ini, pt);

    try {
        auto& so = pt.get_child({"Sensor.Offsets", '#'});
        double x = so.get<double>("x");
        double y = so.get<double>("y");

        fmt::print("[Sensor.Offsets].(x,y) = ({},{})\n", x, y);
    } catch (std::exception& ex) {
        fmt::print("{}\n", ex.what());
        exit(-2);
    }
}

Prints

[Sensor.Offsets].(x,y) = (65,-66.3)

Upvotes: 1

Related Questions