使用nlohmann json解析含Unicode字符的JSON文件时遇解码错误
问题原因
你遇到的错误核心在于:JSON文件里的\xc3\xad是C/C++风格的十六进制字节转义,但JSON标准只认可特定的转义序列:
- 基础转义:
\"、\\、\/、\b、\f、\n、\r、\t - Unicode转义:
\uXXXX(四位十六进制数,对应单个Unicode码点)
nlohmann的JSON解析器严格遵循JSON规范,完全不识别\x开头的转义格式,所以才会抛出unknown character after backslash 'Bras\x'的错误。
解决方案
方案1:修复JSON文件(推荐)
直接把JSON里的C风格转义改成JSON兼容的格式,有两种简单方式:
- 直接使用UTF-8编码的字符
í,修正后的JSON内容:
[ { "code":"BR", "name":"Brazil", "capital":"Brasília" } ]
- 使用JSON标准的Unicode转义
\u00ED(对应字符í),修正后的JSON:
[ { "code":"BR", "name":"Brazil", "capital":"Bras\u00EDlia" } ]
修改完成后,你原来的解析代码就能正常运行了。
方案2:预处理文件内容(无法修改JSON时使用)
如果没办法修改原始JSON文件,可以在解析前先读取文件内容,把\xXX格式的转义转换成对应的UTF-8字节,再交给nlohmann解析。示例代码如下:
#include <fstream> #include <string> #include <regex> #include <stdexcept> #include <nlohmann/json.hpp> using json = nlohmann::json; std::string preprocess_json_content(const std::string& file_path) { // 读取文件全部内容 std::ifstream ifs(file_path); if (!ifs.is_open()) { throw std::runtime_error("Failed to open file"); } std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); // 正则匹配所有 \xXX 格式的转义 std::regex hex_escape(R"(\\x([0-9a-fA-F]{2}))"); content = std::regex_replace(content, hex_escape, [](const std::smatch& match) { // 将十六进制字符串转换为对应的字符 char byte = static_cast<char>(std::stoul(match[1].str(), nullptr, 16)); return std::string(1, byte); }); return content; } int main() { try { std::string processed_content = preprocess_json_content("resources/countries.json"); json j2 = json::parse(processed_content); // 测试输出 std::cout << "Capital of Brazil: " << j2[0]["capital"] << std::endl; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } return 0; }
这段代码会把所有\xXX转义替换成对应的字节,比如\xc3\xad会被转换成UTF-8编码的í字符,这样解析器就能正常处理了。
内容的提问来源于stack exchange,提问作者Arslan
相关产品推荐
相关产品推荐

