将UTF-8文本转换为wchar_t

我知道这个问题在这里已经被问了很多次了,我确实读了一些答案,但是有一些建议的解决方案,我试图找出最好的解决方案。

我正在编写一个基本上接收以UTF-8编码的XML文本的C99应用程序。

它的一部分工作是复制和操作该字符串(找到一个substr,cat it,ex ..)

因为我现在不想使用外部非标准库,我试图使用wchar_t来实现它。

目前,即时通讯使用mbstowcs将其转换为wchar_t以便于操作,对于某些输入我尝试了不同的语言 – 它工作正常。

事实上,我确实读过一些人,因为UTF-8和mbstowcs存在一些问题,所以我想知道这种使用是否被允许/接受。

我遇到的其他选项是使用带有WCHAR_T参数的iconv。 事实上,即时工作在一个平台(而不是PC)上,它的语言环境对ANSI C语言环境非常有限。 那个怎么样?

我也遇到过一些非常受欢迎的C ++库。 但我限制C99实施。

另外,我将在另一个平台上编译此代码,wchar_t的sizeof不同(2个字节对​​比我机器上的4个字节)。 我怎么能克服这个? 使用固定大小的char容器? 但是,我应该使用哪些操作function呢?

很高兴听到一些想法。 谢谢。

C没有定义charwchar_t类型的编码,标准库只强制在两者之间进行转换而不说明如何。 如果char的依赖于实现的编码不是UTF-8,那么mbstowcs将导致数据损坏。

正如C99标准的基本原理所述 :

然而,这五个function往往过于严格,而且过于原始,无法开发管理角色的便携式国际程序。

C90故意选择不发明更完整的多字节和宽字符库,而是选择等待它们的自然发展,因为C社区获得了更多的广泛角色经验。

来自这里 。

因此,如果您的char有UTF-8数据,则没有标准的API方法将其转换为wchar_t

在我看来,除非必要,否则通常应该避免使用wchar_t – 如果您使用的是WIN32 API,则可能需要它。 我不相信它会简化字符串操作。 Windows上的wchar_t始终是UTF-16LE,因此您可能仍需要多个wchar_t来表示单个Unicode代码点。

我建议你调查ICU项目 – 至少从教育的角度来看。

另外,我将在另一个平台上编译此代码,wchar_t的sizeof不同(2个字节对​​比我机器上的4个字节)。 我怎么能克服这个? 使用固定大小的char容器?

您可以使用这样的条件typedef来做到这一点:

 #if defined(__STDC_UTF_16__) typedef _Char16_t CHAR16; #elif defined(_WIN32) typedef wchar_t CHAR16; #else typedef uint16_t CHAR16; #endif #if defined(__STDC_UTF_32__) typedef _Char32_t CHAR32; #elif defined(__STDC_ISO_10646__) typedef wchar_t CHAR32; #else typedef uint32_t CHAR32; #endif 

这将定义CHAR16CHAR32以使用新的C ++ 11字符类型(如果可用),但否则将回退到使用wchar_t和否则使用固定宽度无符号整数。