C++标准库不支持直接读Hjson,因C++20的std::json仅支持严格JSON语法,无法处理注释、无引号键名、多行字符串等Hjson扩展特性,解析时会报“parse error”;必须使用hjson-cpp等第三方库。

为什么C++标准库不支持直接读Hjson
Hjson是JSON的扩展格式,允许注释、省略引号、多行字符串等特性,但C++标准库里的std::json(C++20起)只认严格JSON语法。遇到// 注释或key: value这种写法会直接解析失败,报错类似parse error at 1:3: expected '{' or '['。
所以必须用第三方库——目前最成熟、轻量、头文件即用的是hjson-cpp,它专为Hjson设计,不依赖Boost或其他运行时,编译期开销低。
用hjson-cpp读取配置的最小可行步骤
先通过包管理器安装(推荐v3.2+):
git clone https://github.com/hjson/hjson-cpp.git # 复制 include/hjson/ 到你的项目 include 目录下
然后在代码中:
立即学习“C++免费学习笔记(深入)”;
- 包含头文件:
#include <hjson/hjson.h> - 读文件到
std::string(注意用二进制模式避免Windows换行截断) - 调用
Hjson::parse(),它返回Hjson::Value类型,行为类似std::variant,支持[]下标访问和.as<T>()强转
示例片段:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
std::ifstream f("config.hjson", std::ios::binary);
std::string content((std::istreambuf_iterator<char>(f)),
std::istreambuf_iterator<char>());
auto root = Hjson::parse(content);
std::string host = root["server"]["host"].as<std::string>();
int port = root["server"]["port"].as<int>();常见解析失败原因和绕过方式
不是所有Hjson语法都默认启用。比如默认禁用allowTrailingComma和allowDuplicateKeys,遇到如下内容会报错:
{
name: "app",
version: "1.0", // ← 这里有逗号但后面没字段
}解决方法是传入Hjson::ParseOptions:
options.allowTrailingComma = true-
options.allowDuplicateKeys = true(后出现的键覆盖前一个) -
options.keepWsc = false(默认true,若不需要保留原始空白字符可关掉节省内存)
调用时写成:Hjson::parse(content, options)。
从Hjson Value安全提取数据的注意事项
Hjson::Value不提供自动类型转换,.as<int>()在值是字符串时不会尝试解析数字,而是抛std::runtime_error。所以不能假设配置字段一定存在或类型正确。
- 用
root.isObject()/root.isArray()先判断结构 - 用
root.hasKey("timeout")检查字段是否存在,再取值 - 整数建议统一用
.as<long long>(),避免32位平台溢出 - 字符串尽量用
.asString()而非.as<std::string>()(后者可能触发额外拷贝)
最易被忽略的一点:Hjson解析后的Value对象内部持有原始字符串视图,如果你把content变量提前释放,再访问root["key"]可能得到空字符串或崩溃——必须保证content生命周期长于root及其所有子节点。

















