从json文件获取Unicode

vptzau2j  于 2023-10-21  发布在  其他
关注(0)|答案(1)|浏览(110)

我正在做一个C项目(C14),我面临以下问题。我有一个JSON文件,其字段包含Unicode字符。我正在使用nlohmann/json从这个字段中检索信息。然而,当我取回它时,它并不符合我的期望。下面是我的源代码:

std::u16string Str16 = u"\u9db4\u5c4b\u516b\u5e61 \u4eac\u962a\u767e\u8ca8\u5e97\u5b88\u53e3\u5e97";//L"鶴屋八幡 京阪百貨店守口店"
std::ifstream jsonFile("name.json");

if (!jsonFile.is_open()) {
    std::cerr << "can't open JSON" << std::endl;
    return 1;
}

nlohmann::json jsonData;
jsonFile >> jsonData;

std::string unicodeStr = jsonData["name"];

jsonFile.close();
return 0;

name.json

{
"name": "\u9db4\u5c4b\u516b\u5e61 \u4eac\u962a\u767e\u8ca8\u5e97\u5b88\u53e3\u5e97"
}

我的愿望是能够将Unicode字符串'unicodeStr'转换为'char16_t'字符串或'u16 string'。或者获取unicodeStr =“\u9db4\u5c4b\u516b\u5e61\u4eac\u962a\u767e\u8ca8\u5e97\u5b88\u53e3\u5e97”
有人能帮我解决这个问题吗?

of1yzvn4

of1yzvn41#

你的代码运行良好。问题出在别处。
内存中的所有内容都只是字节值。某些模式表示整数、浮点数、字符或字符串的想法要求您对如何与该内存交互做出假设。值得注意的是,有 * 数百 * 种不同的编码用于以字节存储文本,(其中9种以上的编码具有完全的Unicode支持)并且std::string可以保存...基本上除了三个。
大多数开发人员只是“使用默认值”,在美国版本的Windows上,假设所有文本都以Windows-1252编码存储。开发人员还假设每个“Character”都是1 char,这对于Windows-1252是正确的,但对于许多其他编码是错误的假设。值得注意的是,这个假设对于 * 所有9+ Unicode编码 * 都是不正确的。
然而,nlohmann给你一个std::string,它的内部文本编码为UTF-8。因此,当您的其他代码尝试使用此文本时(例如将其传递给std::cout),其他代码将字节解码为其他编码(可能是Windows-1252),这将导致鶴屋八幡 京阪百貨店守å£åº—。这是一个非常常见的bug,通常称为Mojibake(请注意,示例图像中的文本甚至看起来与您的结果几乎相同)
通常有两种方法来解决这个问题:

  • 看起来很简单,其实很难:使用一些库将utf-8文本转换为程序其余部分使用的编码。一些库是ICUboostWindows APIs。但是,代码的其余部分将无法正确处理Unicode文本。
  • 看起来很难,其实很容易:修复整个程序,将std::string解释为UTF8。Windows为此提供了帮助器方法,但Linux通常只是默认执行此操作。

相关问题