讲师中心 微信公众号
AI工具推荐 视频效率加速

c++如何读取和解析带注释的YAML配置文件_轻量级方案【详解】

落丽姑娘_5559

落丽姑娘_5559

发布时间:2026-04-01 15:35:37

|

967人浏览过

|

来源于php中文网

原创

直接用 yaml-cpp(v0.8.0+且启用YAML_CPP_BUILD_CONTRIB=ON),它封装libyaml、提供C++ API、支持注释保留与类型推导;libyaml为纯C,需手动处理事件流和注释,工程成本高。

c++如何读取和解析带注释的yaml配置文件_轻量级方案【详解】

YAML 解析器选 yaml-cpp 还是 libyaml?

直接用 yaml-cpp。它封装了 libyaml 的 C 接口,提供 C++ 风格的 API,支持注释保留(从 v0.8.0 起)、类型推导和异常友好;而原生 libyaml 是纯 C,需手动管理事件流,读注释得自己解析 token,工程成本高得多。

注意:v0.7.x 及更早版本的 yaml-cpp 不保留注释——必须升级到 v0.8.0+,且启用构建选项 YAML_CPP_BUILD_CONTRIB=ON(否则 Node::Mark() 和注释访问接口不可用)。

  • Ubuntu/Debian 下 apt 安装的 libyaml-cpp-dev 通常是 v0.6.x,不满足要求
  • 推荐用 vcpkg 或 conan 拉取最新版,或从源码编译:cmake -DYAML_CPP_BUILD_CONTRIB=ON ..
  • 注释不是“自动附着在键上”的——它属于某个 Node 的 Mark 位置,需结合 Node::size() 和遍历顺序手动对齐

怎么读取文件并保留注释信息?

yaml-cpp 默认解析会丢弃所有注释。要拿到注释,必须用 YAML::LoadFile() 后立即调用 node.Mark() 获取行号,再配合 YAML::Parser + YAML::Scanner 手动提取原始文本中的注释行——但这样太重。

更轻量的做法是:改用 YAML::LoadInput 加自定义 YAML::Input,并确保传入的是带 BOM 或 UTF-8 编码的完整字符串(而非直接文件路径),再启用贡献模块后,通过 node.GetMark().input_pos_ 和底层缓冲区反查注释行。不过实践中,90% 的配置场景只需“跳过注释、正确解析结构”,此时只需确认 YAML::LoadFile() 不报错即可。

C++14
C++14

C++14 对 C++11 的修正与增强版本,适合旧系统维护和较老工具链兼容。

下载

立即学习“C++免费学习笔记(深入)”;

  • 真正需要注释内容时(比如生成带注释的回写配置),必须用 YAML::Node::size() 遍历所有子节点,对每个 key 调用 node[key].Mark().line 并比对前后行是否有 # 开头的行
  • Windows 下用 std::ifstream 读文件时记得加 .imbue(std::locale::classic()),否则宽字符/换行符可能错位,导致 Mark().line 偏移不准
  • 不要依赖 node["key"].IsDefined() 判断字段是否存在——它对注释后的空 key 也返回 true;应配合 node["key"].IsNull() 一起看

YAML::BadConversion 错误常见于哪些操作?

这个异常基本只发生在用 as<T>() 强转类型失败时,比如把 "true" 字符串当 bool 读、把 "123abc" 当 int 读,或者把缩进错位的块序列当成 map 解析。

  • 避免方式:优先用 as<T>() 前加 IsScalar() / IsSequence() / IsMap() 类型检查
  • 更安全的写法是用 node["port"].as<int>(8080) 提供默认值,而不是裸调 as<int>()
  • 浮点数字段若写成 timeout: 3.5e-2,as<double>() 可正常解析;但写成 timeout: .5(缺整数位)会触发 BadConversion
  • 嵌套层级过深(>100 层)也可能触发该异常——不是类型问题,而是解析器递归限制,需调大 YAML::MaxRecursionDepth(200)

为什么修改配置后用 YAML::Emitter 回写会丢注释?

YAML::Emitter 是纯输出器,不持有任何输入源信息,它只按当前 Node 结构生成 YAML 文本,不关心原始文件里哪行有注释、哪行是空行。这是设计使然,不是 bug。

如果业务真需要“编辑后保留原有注释”,就得放弃 Emitter,改用字符串替换方案:先用正则提取所有 key: value 行及其紧邻的上一行注释,再按新值替换对应行。简单但脆弱;稳妥做法是用 yaml-cpp v0.8+ 的 YAML::detail::node_data 内部结构(不推荐,属未公开 API)或换用 Python 的 ruamel.yaml 做预处理。

  • 轻量级项目中,建议接受“回写不带注释”这一事实,把注释当作文档,只在源配置模板中维护
  • 若必须保留,可将注释提前提取到 map 中:std::map<:string std::string> comments;</:string>,key 为字段名,value 为注释内容,回写时手动拼接
  • 别试图用 node.Mark() 的列号去定位注释——YAML 允许注释出现在行末,列号无法唯一映射到某条注释
事情说清了就结束。注释保留在 YAML 解析里从来不是“开箱即用”的能力,它游走在标准解析器的边缘,靠的是版本、编译选项、行号对齐和一点手工补位。别指望一个 LoadFile() 调用就搞定。

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

13366

2023.09.14

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

1605

2023.09.14

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

3637

2023.12.21

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

5801

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1698

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

2584

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6004

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

5489

2023.11.24

VibeKnow知识视频制作与导出详解
VibeKnow知识视频制作与导出详解

本专题整理VibeKnow从注册、素材上传、AI生成到预览导出的完整操作,帮助新手快速制作第一条知识讲解视频。

0

2026.10.14

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C++ Core Guidelines
C++ Core Guidelines

共0课时 | 0人学习

C++ Reference
C++ Reference

共0课时 | 0人学习

C++ 官方标准说明
C++ 官方标准说明

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn