C++14项目中nlohmann/json读取Unicode字符串转u16string问题
解决nlohmann/json读取Unicode JSON字段的两种需求
需求1:将JSON字段转为std::u16string
nlohmann/json默认会把JSON中的\uXXXX转义解析为对应的UTF-8编码字符,你直接获取的unicodeStr是UTF-8格式的std::string。要转成std::u16string,需要完成UTF-8到UTF-16的编码转换,C++14可借助<codecvt>和<locale>库实现:
#include <codecvt> #include <locale> // ... 原有读取JSON的代码 ... std::string utf8Str = jsonData["name"]; // 初始化UTF-8到UTF-16的转换器 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> converter; std::u16string u16Str = converter.from_bytes(utf8Str); // 此时u16Str与你定义的Str16内容完全一致
注:部分编译器对<codecvt>支持存在差异,若编译报错,可替换为utf8cpp等第三方UTF处理库。
需求2:直接获取带\uXXXX转义序列的字符串
如果要保留JSON里原始的\uXXXX转义格式而非解析后的字符,可将解析得到的UTF-8字符串重新格式化为转义序列:
#include <sstream> #include <iomanip> std::string toUnicodeEscape(const std::string& utf8Str) { std::ostringstream oss; for (size_t i = 0; i < utf8Str.size();) { unsigned char c = utf8Str[i]; uint32_t codePoint = 0; // 解析UTF-8字节序列得到Unicode码点 if ((c & 0x80) == 0) { codePoint = c; i += 1; } else if ((c & 0xE0) == 0xC0) { codePoint = ((c & 0x1F) << 6) | (utf8Str[i+1] & 0x3F); i += 2; } else if ((c & 0xF0) == 0xE0) { codePoint = ((c & 0x0F) << 12) | ((utf8Str[i+1] & 0x3F) << 6) | (utf8Str[i+2] & 0x3F); i += 3; } else if ((c & 0xF8) == 0xF0) { codePoint = ((c & 0x07) << 18) | ((utf8Str[i+1] & 0x3F) << 12) | ((utf8Str[i+2] & 0x3F) << 6) | (utf8Str[i+3] & 0x3F); i += 4; } // 保留原始空格,其他字符转为\uXXXX格式 if (codePoint == 0x20) { oss << ' '; } else { oss << "\\u" << std::hex << std::setw(4) << std::setfill('0') << codePoint; } } return oss.str(); } // ... 原有读取JSON的代码 ... std::string utf8Str = jsonData["name"]; std::string escapedStr = toUnicodeEscape(utf8Str); // escapedStr即为你需要的"\u9db4\u5c4b\u516b\u5e61 \u4eac\u962a\u767e\u8ca8\u5e97\u5b88\u53e3\u5e97"
额外说明
- nlohmann/json默认以UTF-8存储字符串,解析
\uXXXX转义是符合JSON标准的行为; - 若JSON文件本身是UTF-16编码,需用
std::wifstream读取,并配合nlohmann/json的宽字符解析接口。
内容的提问来源于stack exchange,提问作者KaiAkiho
相关产品推荐
相关产品推荐

