我有一个JSON文件,包含以下内容(例如):
{
"excel_filepath": "excel_file.xlsx",
"line_length": 5.0,
"record_frequency": 2.5,
"report_file_name": "\u041f\u0421 \u041f\u0440\u043e\u043c\u0437\u043e\u043d\u0430 - \u041f\u0421 \u041f\u043e\u0433\u043e\u0440\u0435\u043b\u043e\u0432\u043e (\u0426.1)",
"line_type": 1,
}
此JSON文件由Python脚本生成。
为了阅读JSON文件,我使用<nlohmann/json.hpp>
库(我发现它对我的情况很简单):
using json = nlohmann::json;
std::ifstream f("temp_data.json");
json data = json::parse(f);
我要做的是读取"report_file_name"
值,并创建一个简单的.txt
文件,命名为report_file_name
键的值,它以Unicode存储,如您所见。
我正在努力做的事情如下:
_setmode(_fileno(stdout), _O_U16TEXT);
const locale utf8_locale = locale(locale(), new codecvt_utf8<wchar_t>());
string report_file_name = data["report_file_name"];
for (auto unicode_char : report_file_name)
{
wcout << typeid(unicode_char).name() << ": " << unicode_char << endl;
}
wofstream report_file(report_file_name + L".txt");
report_file.imbue(utf8_locale);
这将给出如下输出:
char: Ð
char:
char: Ð
char: ¡
char:
char: Ð
char:
char: Ñ
char:
char: Ð
char: ¾
... and so on
我必须指出,我设法将西里尔字母写入报告文件。有趣的是,当我这样做时:
wcout << L"\u041f\u0421" << endl;
它可以正确地打印出西里尔字母(ПС
)。另外,使用以下代码创建具有西里尔名称的报告.txt
文件也没有问题:
wofstream report_file(L"Отчет.txt"); // fine!
我做错了什么吗?我使用的是Windows 10,MVS 2022与C++17标准。如果这是有帮助的。
1条答案
按热度按时间svmlkihl1#
根据
nlohmann::json
的文档:https://github.com/nlohmann/json#character-encoding
字符编码
库支持Unicode输入,如下所示:
std::u16string
和std::u32string
,分别采用UTF-16和UTF-32编码。从文件或其他输入容器阅读时不支持这些编码。\uDEAD
等不完整的对)将产生解析错误。***存储在库中的字符串是UTF-8编码的。**使用默认字符串类型(
std::string
)时,请注意其length/size函数返回的是存储的字节数,而不是字符或字形数。dump()
可能会引发异常,除非将json::error_handler_t::replace
或json::error_handler_t::ignore
用作错误处理程序。*要存储宽字符串(例如
std::wstring
),您需要在之前将其转换为UTF-8编码的std::string
,请参见示例。因此,在您的情况下,您的
report_file_name
字符串是UTF-8编码的std::string
,您需要将其解码为std::wstring
(Windows上为UTF-16,其他平台上为UTF-32),然后才能将其用于std::wofstream
,例如: