C11 和 C++11 都引入了uchar.h
/cuchar
标头,明确定义char16_t
了char32_t
16 位和 32 位宽字符,添加了文字语法u""
和U""
用于编写具有这些字符类型的字符串,以及宏__STDC_UTF_16__
,并__STDC_UTF_32__
告诉您它们是否对应于 UTF-16和 UTF-32 代码单元。这有助于消除关于 的歧义wchar_t
,在某些平台上是 16 位,通常用于保存 UTF-16 代码单元,而在某些平台上是 32 位,通常用于保存 UTF-32 代码单元;假设现在设置了这些宏,您现在可以编写引用 UTF-16 和 UTF-32 的可移植、明确的代码。__STDC_ISO_10646__
也可以作为代理来判断是否wchar_t
能够保存 UTF-32 值;如果不能,您不一定能假设它拥有 UTF-16,但它可能是一个足够接近可移植的近似值。
他们还添加了函数mbrtoc16
、mbrtoc32
、c16rtomb
和c32rtomb
,用于在多字节字符和这些类型之间进行转换。在这些和现有mbstowcs
的函数系列之间,可以在 UTF-16、UTF-32、平台多字节字符集和平台宽字符集之间进行可移植的转换(尽管不一定无损,除非平台定义的多字节和宽字符集是UTF;特别是,在 Windows 上,这些函数似乎毫无用处,其中语言环境定义的多字节编码不允许每个字符使用超过两个字节)。
此外,他们添加了u8""
用于编写文字 UTF-8 编码字符串的语法。char *
由于 UTF-8 是一种与处理和的大多数函数兼容的编码,因此std::string
这是最有用的新增功能之一。
但是,他们似乎没有添加任何方法来在 UTF-8、UTF-16 和 UTF-32 之间进行可移植转换。和mbtoc16
相关函数在实现定义的多字节编码和 UTF-16 或 32 之间进行转换;但你不能依赖这是 UTF-8。在类 Unix 平台上,它依赖于语言环境,其中许多默认情况下在其语言环境中使用 UTF-8,即使它不是默认设置,您至少可以将语言环境设置为 UTF-8 语言环境以便了解“多字节”表示 UTF-8。但是,在 Windows 上,您不能明确地使用 UTF-8 或任何其他需要超过两个字节的 locale 编码。
我只是遗漏了什么,还是 UTF-8 字符串类型没有任何方式将其转换为其他类型的字符串:平台定义的多字节、平台定义的宽字符、UTF-16 或 UTF-32?甚至无法判断您的系统多字节编码是否为 UTF-8?是否有任何理由不包括这种支持(具体来说,我正在寻找 C 或 C++ 标准委员会的实际书面理由或讨论,而不仅仅是猜测)?是否正在做任何工作来改善这种情况?未来有可能改善吗?
或者,如果您想以可移植的方式支持 UTF-8、编写自己的实现、引入库依赖项或使用特定于平台的函数(如iconv
和),是当前最好的解决方案MultiByteToWideChar
吗?