如何在yaml-cpp中为字符串值统一加双引号且不影响键?
使用yaml-cpp实现仅字符串值统一带双引号的解决方案
核心问题原因
yaml-cpp的Emitter默认会根据标量内容自动判断是否添加引号:
- 像
*这类YAML特殊字符会被自动加双引号 - 类似
10.0.0.1这类符合无引号标量规则的字符串,会直接输出不带引号 - 全局设置
SetStringFormat(YAML::DoubleQuoted)会同时给键和值都加上双引号,不符合需求
解决方案1:逐个值指定格式
在输出每个字符串值时,显式指定YAML::DoubleQuoted格式,键保持默认输出:
YAML::Emitter yaml_out; yaml_out << YAML::BeginMap; // 输出带引号的通配符IP yaml_out << YAML::Key << "ip" << YAML::Value << YAML::DoubleQuoted << "*"; // 输出带引号的普通IP yaml_out << YAML::Key << "static_ip" << YAML::Value << YAML::DoubleQuoted << "10.0.0.1"; // 数值、布尔值不受影响,正常输出 yaml_out << YAML::Key << "port" << YAML::Value << 8080; yaml_out << YAML::Key << "enabled" << YAML::Value << true; yaml_out << YAML::EndMap;
输出结果:
ip: "*" static_ip: "10.0.0.1" port: 8080 enabled: true
解决方案2:批量处理字符串值(自定义递归输出)
如果需要批量处理所有字符串值,可通过自定义递归输出函数,标记并强制字符串值带引号:
- 赋值时给需要带引号的字符串添加自定义标签:
YAML::Node ip_map; // 标记为需要强制带引号的字符串 ip_map["ip"] = YAML::Tag("!str", "*"); ip_map["static_ip"] = YAML::Tag("!str", "10.0.0.1"); ip_map["port"] = 8080; ip_map["enabled"] = true;
- 编写递归输出函数处理节点:
void EmitNode(YAML::Emitter& out, const YAML::Node& node) { if (node.IsMap()) { out << YAML::BeginMap; for (auto it = node.begin(); it != node.end(); ++it) { out << YAML::Key << it->first; out << YAML::Value; // 识别自定义标签的字符串,强制双引号输出 if (it->second.IsScalar() && it->second.Tag() == "!str") { out << YAML::DoubleQuoted << it->second.as<std::string>(); } else { EmitNode(out, it->second); } } out << YAML::EndMap; } else if (node.IsSequence()) { out << YAML::BeginSeq; for (const auto& item : node) { if (item.IsScalar() && item.Tag() == "!str") { out << YAML::DoubleQuoted << item.as<std::string>(); } else { EmitNode(out, item); } } out << YAML::EndSeq; } else if (node.IsScalar()) { if (node.Tag() == "!str") { out << YAML::DoubleQuoted << node.as<std::string>(); } else { out << node; } } }
- 使用自定义函数输出:
YAML::Emitter yaml_out; EmitNode(yaml_out, ip_map);
针对读取后强制输出带引号的场景
读取fileA中的IP值后,输出时同样用YAML::DoubleQuoted包裹即可:
// 读取fileA内容 YAML::Node doc = YAML::LoadFile("fileA"); std::string ip_val = doc["original_ip"].as<std::string>(); // 输出时强制带双引号 YAML::Emitter yaml_out; yaml_out << YAML::BeginMap; yaml_out << YAML::Key << "ip" << YAML::Value << YAML::DoubleQuoted << ip_val; yaml_out << YAML::EndMap;
输出结果:
ip: "10.0.0.1"
内容的提问来源于stack exchange,提问作者Phippsy
相关产品推荐
相关产品推荐

