如何禁用yaml-cpp Emitter自动在新Map前添加---文档起始符?
解决yaml-cpp生成多文档分隔符的问题
嘿,我太懂你碰到的这个坑了——其实根本不用改yaml-cpp的源码,是咱们对文档结构的实现思路错了,调整几行代码就能完美解决!
问题根源
你现在的代码每次循环都调用YAML::BeginMap和YAML::EndMap,相当于在YAML文档的根级别生成了N个独立的Map对象。而根据YAML规范,根级别存在多个独立节点时,会被识别为多个文档,yaml-cpp就自动用---作为文档分隔符,这就是为什么每个Map前都出现了分隔符。
你的需求是把所有图片元数据放在同一个文档的根Map里,这样才能通过frame_id直接索引访问,所以核心是要把所有键值对包裹在一个根Map中,而不是每次循环都新建Map。
修正后的基础代码示例
把BeginMap移到循环外面,EndMap移到循环之后,循环内部只需要输出每个Key和对应的Value:
YAML::Emitter res; res << YAML::BeginDoc; // 先开启一个根Map,所有frame_id都放在这个Map里 res << YAML::BeginMap; for (int i = 0; i < 5; i++) { // 循环内仅输出键值对,无需重复创建Map res << YAML::Key << i << YAML::Value << 42; } res << YAML::EndMap; // 关闭根Map res << YAML::EndDoc; std::cout << res.c_str() << std::endl;
输出结果就会是你期望的单个文档结构:
--- 0: 42 1: 42 2: 42 3: 42 4: 42
适配你的复杂元数据场景
针对你带Algorithm嵌套的复杂结构,只需要在根Map下,为每个frame_id创建对应的子Map即可,代码调整如下:
YAML::Emitter res; res << YAML::BeginDoc << YAML::BeginMap; // 开启根Map for (int frame_id = 3; frame_id <= 4; frame_id++) { // 为当前frame_id创建子Map res << YAML::Key << frame_id << YAML::Value << YAML::BeginMap; // 写入Algorithm 1的序列数据 res << YAML::Key << "Algorithm 1" << YAML::Value << YAML::BeginSeq; res << YAML::Flow << YAML::BeginSeq << 162 << 14 << 13 << 14 << YAML::EndSeq; res << YAML::Flow << YAML::BeginSeq << 18 << 1 << 90 << 30 << YAML::EndSeq; res << YAML::EndSeq; // 写入Algorithm 2的序列数据 res << YAML::Key << "Algorithm 2" << YAML::Value << YAML::BeginSeq; res << YAML::Flow << YAML::BeginSeq << 195 << 9 << 57 << 73 << YAML::EndSeq; res << YAML::Flow << YAML::BeginSeq << 135 << 22 << 101 << 31 << YAML::EndSeq; res << YAML::EndSeq; res << YAML::EndMap; // 关闭当前frame_id的子Map } res << YAML::EndMap << YAML::EndDoc; // 关闭根Map和文档
生成的YAML结构完全符合你的查询需求:
--- 3: Algorithm 1: - [162, 14, 13, 14] - [18, 1, 90, 30] Algorithm 2: - [195, 9, 57, 73] - [135, 22, 101, 31] 4: Algorithm 1: - [216, 10, 14, 13] - [24, 0, 91, 29] Algorithm 2: - [260, 6, 58, 72] - [180, 16, 102, 30]
这样后续读取时,就能直接通过myyaml[frame_id]["Algorithm 2"][0]这类方式快速访问对应元数据了。
内容的提问来源于stack exchange,提问作者oohshiny
相关产品推荐
相关产品推荐

