如何使用C++读取config.yaml并解析键值对与嵌套数组
使用ryml库读取YAML中的键值对与嵌套数组
问题场景
需要用C读取config.yaml文件,基于ryml库编写代码时遇到解析问题:无法将YAML中的键值对(如height、width)以及嵌套数组结构(如dist2、R这类包含数组的内容)转换为C的vector等数据类型。
原代码如下:
#include <typeinfo> #include <ryml_std.hpp> #include <ryml.hpp> std::string get_file_contents(const char* filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (!in) { std::cerr << "could not open " << filename << std::endl; exit(1); } std::ostringstream contents; contents << in.rdbuf(); //std::cout << contents.str() << std::endl; return contents.str(); } int main(int argc, char const* argv[]) { try { std::string contents = get_file_contents("C:/yaml/config.yaml"); ryml::Tree tree = (ryml::parse(ryml::to_csubstr(contents))); std::vector<float> data; tree[0] >> data; // 此处解析失败 tree[3] >> width; } catch(std::exception &e){ std::cout << e.what() <<std::endl; } }
对应的config.yaml内容:
dist2: - - 0.045533736417839546 - 0.16564066086021373 - 0.028658520327566304 - 0.009133486414620372 - -0.5801749091384203 height: 480 rms: 1.6671979326607804 width: 640 R: - - 0.986119137868725 - 0.04723012789836373 - -0.15918027813691865 - - -0.07869384510750799 - 0.9771216529170358 - -0.19758682684550466 - - 0.1462064453819944 - 0.2073706594949828 - 0.9672750823366525
解决代码
以下是修正后的完整代码,可以正确读取所有键值对和嵌套数组:
#include <iostream> #include <fstream> #include <sstream> #include <vector> #include <ryml_std.hpp> #include <ryml.hpp> std::string get_file_contents(const char* filename) { std::ifstream in(filename, std::ios::in | std::ios::binary); if (!in) { std::cerr << "could not open " << filename << std::endl; exit(1); } std::ostringstream contents; contents << in.rdbuf(); return contents.str(); } int main(int argc, char const* argv[]) { try { std::string contents = get_file_contents("C:/yaml/config.yaml"); ryml::Tree tree = ryml::parse(ryml::to_csubstr(contents)); // 读取嵌套数组dist2(二维vector) std::vector<std::vector<float>> dist2; tree["dist2"] >> dist2; // 读取基本类型键值对 int height = 0; tree["height"] >> height; double rms = 0.0; tree["rms"] >> rms; int width = 0; tree["width"] >> width; // 读取嵌套数组R(二维vector) std::vector<std::vector<float>> R; tree["R"] >> R; // 验证读取结果(可选) std::cout << "height: " << height << std::endl; std::cout << "width: " << width << std::endl; std::cout << "rms: " << rms << std::endl; std::cout << "dist2 size: " << dist2.size() << std::endl; std::cout << "R size: " << R.size() << std::endl; } catch(const std::exception& e){ std::cerr << e.what() << std::endl; } return 0; }
关键修正点
- 用键名访问节点:原代码用索引(
tree[0]、tree[3])访问,但你的YAML是映射结构(键值对集合)而非序列,必须通过键名(如tree["dist2"]、tree["width"])来定位节点。 - 匹配嵌套数组类型:
dist2和R是二维数组,对应C++的std::vector<std::vector<float>>类型,而非一维std::vector<float>。 - 声明变量类型:读取基本类型(
height、width、rms)时,要提前声明对应类型的变量,ryml会自动完成类型转换。 - 补充必要头文件:添加了
<iostream>、<vector>等基础头文件,保证代码编译通过。
内容的提问来源于stack exchange,提问作者REDDY
相关产品推荐
相关产品推荐

