C++11 不使用中间缓冲将UTF-8编码文件读入std::u32string 使用Unicode和C++ C++工作了很长时间,我认为这是一个简单的事情,尤其是在新的C++ 11代码> STD::CODECVTTUTF8方面。尽管这是一项艰巨的任务。我想要的是将UTF-8编码的文件读入u32string(隐式地将其从UTF-8转换为UTF-32)。当然,我可以将整个内容加载到缓冲区中,并使用std::wstring\u convert进行转换。但在加载文件时,这会使内存占用增加一倍。因此,我尝试使用std::wifstream并在区域设置中嵌入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; std::u32string data; for (wchar_t c; stream >> c; ) data += c;

C++11 不使用中间缓冲将UTF-8编码文件读入std::u32string 使用Unicode和C++ C++工作了很长时间,我认为这是一个简单的事情,尤其是在新的C++ 11代码> STD::CODECVTTUTF8方面。尽管这是一项艰巨的任务。我想要的是将UTF-8编码的文件读入u32string(隐式地将其从UTF-8转换为UTF-32)。当然,我可以将整个内容加载到缓冲区中,并使用std::wstring\u convert进行转换。但在加载文件时,这会使内存占用增加一倍。因此,我尝试使用std::wifstream并在区域设置中嵌入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; std::u32string data; for (wchar_t c; stream >> c; ) data += c;,c++11,C++11,(至少在使用clang时,VC++也接受char32_t,但这不会改变任何事情)。解决此问题后,仍存在其他几个问题,但: 在VisualC++中,WHARCHART只有16位(没有UTF 32,那么,我们不考虑代理对)。 将char32\t用于刻面基本上禁用了转换。流上的迭代返回原始UTF-8内容,包括clang和VC++ 同样对facet使用wchar\u t使它在clang中工作,但在VC++中不工作,因为clangwchar\u t的宽度为32位,而(如前所述)在VC++中仅为16位

(至少在使用clang时,VC++也接受char32_t,但这不会改变任何事情)。解决此问题后,仍存在其他几个问题,但:

  • 在VisualC++中,WHARCHART只有16位(没有UTF 32,那么,我们不考虑代理对)。
  • char32\t
    用于刻面基本上禁用了转换。流上的迭代返回原始UTF-8内容,包括clang和VC++
  • 同样对facet使用
    wchar\u t
    使它在clang中工作,但在VC++中不工作,因为clang
    wchar\u t
    的宽度为32位,而(如前所述)在VC++中仅为16位

那么,这里的正确方法是什么?由于对facet的wchar\t进行了锁定,我甚至无法使用不同的数据类型。我还尝试定义一个
basic\u ifstream
,但这需要额外的typedef,因此我没有进一步遵循这条路径。

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

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);
}
void load(标准::istream&stream)
{
静态标准::wstring_convert utfConverter;
std::string s((std::istreambuf_迭代器(stream)),std::istreambuf_迭代器();
_数据=utfConverter.from_字节;
}

wifstream
basic\u ifstream
。尝试使用
basic\u ifstream
@IgorTandetnik,正如我在问题中所写的,我已经尝试过了,但仅此一点并不能解决问题。对于basic_ifstream使用的类型,它需要更多的typedef。我真的不明白你的问题是什么。您是否在问如何解决
wchar\u t
类型在Clang和MSVC上的大小不同的问题?没有魔法。根据环境的不同,您只需对适当大小的类型使用typedef。你能解释为什么“这需要额外的typedef”是一个停止播放的问题吗?嗯,读取UTF-8数据很简单,读取UTF-16数据也很简单,所以我相信对于UTF-32来说,这样做应该同样简单。我只是没有找到正确的方法。定义自定义流类型是一个选项,但看起来似乎需要大量工作。它不是通过定义流typedef来完成的。