Reputation: 252
I want to read the following yaml data:
camera:
response_values: [[0.0: 0.0, 1.0: 1.1, 245.0: 250.1], [0.0: 0.1, 1.0: 1.3, 200.0: 250], [0.0: 0.0, 1.0: 1.1, 245.0: 250.1]]
I want to read it into a vector < map <float, float> >
. In this case, the vector would have 3 maps with each 3 entries.
My attempt is this:
#include <yaml-cpp/yaml.h>
#include <fstream>
#include <map>
using namespace std;
int main()
{
YAML::Node camerafile = YAML::LoadFile("/path/to/camera.yaml");
YAML::Node camera = camerafile["camera"];
auto response_values_yaml = camera["response_values"];
for(YAML::const_iterator it=response_values_yaml.begin();it!=response_values_yaml.end();++it) {
YAML::Node response_values_map = it->as<YAML::Node>(); // e.g. [0.0: 0.0, 1.0: 1.1, 245.0: 250.1]
string whole_map = YAML::Dump(response_values_map);
for(YAML::const_iterator at=response_values_map.begin();at!=response_values_map.end();++at) {
auto the_thing = at->as<YAML::Node>();
string the_string = YAML::Dump(the_thing);
float key = at->first.as<float>();
float val = at->second.as<float>();
}
}
}
Debug results:
whole_map
: "[{0.0: 0.0}, {1.0: 1.1}, {245.0: 250.1}]"
the_string
: "{0.0: 0.0}"
the_thing
->Node->Ref->Data has a map item
However, as soon as the program reaches float key = at->first.as<float>();
, it crashes.
terminate called after throwing an instance of 'YAML::InvalidNode'
what(): invalid node; this may result from using a map iterator as a sequence iterator, or vice-versa
GDB jumps into yaml-cpp/node/imlp.h
. this
is an empty node with m_isValid
being false
.
Trying as<string>
produces the same behaviour. I think I have a map, but I can't interpret it as a map using the .first
and .second
methods, I think this is what the error messages tells me. What am I missing?
Upvotes: 3
Views: 1124
Reputation: 3845
#include <assert.h>
#include <fstream>
#include <iostream>
#include <map>
#include <yaml-cpp/yaml.h>
using namespace std;
int main() {
YAML::Node camerafile = YAML::LoadFile("./camera.yaml");
YAML::Node camera = camerafile["camera"];
auto response_values_yaml = camera["response_values"];
// it is the sequence iterator
for (YAML::const_iterator it = response_values_yaml.begin();
it != response_values_yaml.end(); ++it) {
YAML::Node response_values_map
= it->as<YAML::Node>(); // e.g. [0.0: 0.0, 1.0: 1.1, 245.0: 250.1]
for (YAML::const_iterator at = response_values_map.begin();
at != response_values_map.end(); ++at) {
// `at` is a **map iterater** which has a single key/value pair.
// so it will certainly coredump when you are calling `at->first.as<float>()`
assert(at->size() == 1);
// The iterator points to the single key/value pair.
YAML::Node::const_iterator sub_it = at->begin(); // **The key point.**
// Then access the key and value.
float key = sub_it->first.as<float>();
float value = sub_it->second.as<float>();
std::cout << " key: " << key << ", val: " << value << '\n';
}
}
}
The output will look likes this:
key: 0, val: 0
key: 1, val: 1.1
key: 245, val: 250.1
key: 0, val: 0.1
key: 1, val: 1.3
key: 200, val: 250
key: 0, val: 0
key: 1, val: 1.1
key: 245, val: 250.1
Upvotes: 1