gpt4 book ai didi

c++ - 读取多语言文件 - wchar_t vs char?

转载 作者:太空狗 更新时间:2023-10-29 20:08:55 24 4
gpt4 key购买 nike

了解 unicode、语言环境、宽字符和转换对我来说是一次可怕的经历。

我需要同时阅读一个包含俄文、英文、中文和乌克兰文字符的文本文件

我的方法是以字节 block 的形式读取文件,然后在单独的线程上对 block 进行操作以实现快速读取。 (Link)

这是使用 std::ifstream.read(myChunkBuffer, chunk_byteSize) 完成的

但是,我知道如果我坚持使用 char,我的多语言文件中的任何字符都无法通过 255 种组合来表示。


就此而言,我将所有内容都转换为 wchar_t 并希望一切顺利。

我也知道 Sys.setlocale(locale = "Russian") (Link)但它不会将每个 字符解释为俄语吗?在解析字节时,我不知道何时在我的 4 种语言之间切换。

在 Windows 操作系统上,我可以创建一个 .txt 文件并写入“Привет!你好!”在 Notepad++ 程序中,它将保存文件并使用相同的字母重新打开。它是否以某种方式 secret 地在每个字符后添加不可见的标记,以知道何时解释为俄语,何时解释为英语?


我目前的理解是:将所有内容都作为 wchar_t(双字节),将任何文件解释为 UTF-16(双字节)- 是否正确?

另外,我希望保持代码跨平台。

对不起菜鸟

最佳答案

好了,让我们开始吧。让我们针对从 UTF-8 编码文件中读取文本并将其转换为宽字符串而不丢失任何信息的特定问题提供实用解决方案。

一旦我们可以做到这一点,我们就应该没问题,因为这里介绍的实用函数通常会处理所有 UTF-8 到宽字符串的转换(反之亦然),而这正是您所缺少的关键。

那么,首先,您将如何读入您的数据?嗯,这很容易。因为,在一个层面上,UTF-8 字符串只是 chars 的序列,出于多种目的,您可以简单地以这种方式处理它们。所以你只需要做你会为任何文本文件做的事情,例如:

std::ifstream f;
f.open ("myfile.txt", std::ifstream::in);
if (!f.fail ())
{
std::string utf8;
f >> utf8;
// ...
}

到目前为止一切顺利。这一切看起来都很简单。

但是现在,为了更容易地处理我们刚刚读入的字符串(因为在代码中处理多字节字符串非常痛苦),我们需要将其转换为所谓的宽字符串在我们尝试用它做任何事情之前。这些实际上有几种风格(因为不确定 wchar_t 在任何特定平台上的实际“宽度”),但现在我会坚持使用 wchar_t 为了让事情变得简单,进行这种转换实际上比您想象的要容易。

所以,事不宜迟,这是您的转换函数(这就是您买票的目的):

#include <string>
#include <codecvt>
#include <locale>

std::string narrow (const std::wstring& wide_string)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.to_bytes (wide_string);
}

std::wstring widen (const std::string& utf8_string)
{
std::wstring_convert <std::codecvt_utf8 <wchar_t>, wchar_t> convert;
return convert.from_bytes (utf8_string);
}

我的天,这很容易,为什么这些门票一开始就这么贵?

我想这就是我真正需要说的。我认为,根据您在问题中所说的内容,您已经对自己想要做什么有了一个清晰的认识,只是不知道如何实现它(也许还没有完全结合所有的点yet) 但以防万一有任何挥之不去的困惑,一旦你确实有一个宽字符串,你就可以自由地使用所有 std::basic_string 的方法,一切都会'只是工作'。如果您需要将其转换回 UTF-8 字符串以(比如说)将其写出到文件中,那么,现在这很简单。

测试程序超优Wandbox .稍后我会修改这个帖子,还有一些话要说。现在是早餐时间 :) 如有任何问题,请在评论中提出。

注释(作为编辑添加):

  • codecvt 在 C++17 中被弃用(不知道为什么),但如果您将它的使用限制在这两个函数上,那么它真的没有什么可担心的。如果出现更好的情况,人们总是可以重写这些内容(提示,提示,亲爱的标准人员)。
  • codecvt 我相信可以处理其他字符编码,但就我而言,谁在乎呢?
  • 如果 std::wstring(基于 wchar_t)不能在您的特定平台上为您剪裁,那么您始终可以使用 std::u16stringstd::u32string

关于c++ - 读取多语言文件 - wchar_t vs char?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51352190/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com