gpt4 book ai didi

c++11 - 在没有中间缓冲的情况下将 UTF-8 编码文件读入 std::u32string

转载 作者:行者123 更新时间:2023-12-02 01:24:27 24 4
gpt4 key购买 nike

使用 Unicode 和 C++ 工作了很长时间,我认为这很容易完成,尤其是使用新的 C++11 std::codecvt_utf8方面。尽管事实证明这是一项艰巨的任务。我想要的是将以 UTF-8 编码的文件读入 u32string(将其从 UTF-8 隐式转换为 UTF-32)。当然,我可以将整个内容加载到缓冲区中并使用 std::wstring_convert 进行转换.但这会在加载文件时加倍内存占用。所以我尝试使用 std::wifstream 并为语言环境注入(inject) utf-8 方面,如下所示:

std::wifstream stream(fileName, std::ios::binary);
stream.imbue(std::locale(stream.getloc(), new std::codecvt_utf8<char32_t, 0x10ffff, std::consume_header>));

std::u32string data;
for (char32_t c; stream >> c; )
data += c;

这看起来像是一个直接的实现。它只是不编译。 wifstream 的元素类型是 wchar_t , 所以你只能使用 wchar_t在循环中,像这样:

std::u32string data;
for (wchar_t c; stream >> c; )
data += c;

(至少对于 clang,VC++ 也接受 char32_t,但这并没有改变任何东西)。解决此问题后,仍然存在其他几个问题:

  • 在 Visual C++ 中,wchar_t 只有 16 位(没有 UTF-32,我们在这里不考虑代理对)。
  • 使用 char32_t因为 facet 基本上禁用了转换。对流的迭代返回原始的 UTF-8 内容,包括 clang 和 VC++。
  • 使用 wchar_t同样对于 facet 来说,它可以在 clang 中工作,但不能在 VC++ 中工作,因为在 clang 中 wchar_t是 32 位宽,而(如前所述)它在 VC++ 中只有 16 位。

那么,这里正确的方法是什么?由于对 wchar_t 的锁定,我什至不能使用不同的数据类型。我还尝试定义一个 basic_ifstream<char32_t>但这需要额外的 typedef,因此我没有进一步遵循该路径。

最佳答案

似乎没有办法使用分面并将其注入(inject)流中,所以我使用了一个中间缓冲区,这也是一个非常优雅的解决方案,只是它加倍(或多或少)加载内容所需的内存.使用二进制模式的字节(文件)流来调用这个:

void load(std::istream &stream)
{
static std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> utfConverter;

std::string s((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
_data = utfConverter.from_bytes(s);
}

关于c++11 - 在没有中间缓冲的情况下将 UTF-8 编码文件读入 std::u32string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37945402/

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