将UTF-16(Windows上为wchar_t)转换为UTF32

时间:2016-02-24 22:21:20

标签: c++ winapi unicode

我有一个由Windows API函数(带有LOCALE_SLONGDATE的GetLocaleInfoEx)给我的字符串作为wchar_t。说从Windows返回的值是UTF-16是正确的,因此它可能不是一个wchar_t,一个"可打印的字符"?

为了使我的解析器编写更容易,是否有一个我可以用来将UTF-16转换为UTF-32的函数,我保证(我假设),一个数组元素代表一个字符?

2 个答案:

答案 0 :(得分:3)

  

我保证(我假设),一个数组元素代表一个字符?

这不是Unicode的工作方式。一个代码点(UTF-32中的数组元素)不会必然映射到单个可见字符。由于Unicode组合字符等功能,多个代码点可以组合形成一个字符。

如果您想知道Unicode字符串有多少可见字符,则必须进行真正的Unicode分析。

即使有日期(特别是您要求的长日期),您也无法安全地使用这些功能。语言环境可以返回任意Unicode字符串,因此您无法从代码点的数量知道Unicode字符串的长度。

答案 1 :(得分:1)

查看documentation for LOCALE_SLONGDATE,声明格式图片以外的任何字符必须用单引号括起来。所以在这种特殊情况下转换为UTF-32应该可以解决你的问题(但请参阅下面的附带条款)。

但是,出于同样的原因,你并不需要。唯一不代表单个UTF-32字符的UTF-16字符是代理字符,其中没有一个可以被误认为是单引号。因此,要从周围文本中分离出格式图片,您只需要扫描UTF-16字符串以获得单引号。 (UTF-8的情况也是如此;看起来像单引号的唯一字节是单引号。)

任何代理对,组合字符或其他复杂情况应始终安全地隐藏在由此划分的子串中。如果您从不尝试细分子串本身,那么您应该是安全的。

Proviso:文档没有说明是否允许将单引号与组合字符组合在一个语言环境中,如果允许,将如何解释它。我认为这意味着这样的组合允许。无论如何,Windows本身似乎不太可能遇到处理这种不必要的复杂问题的麻烦。所以它应该足够安全,也可以忽略这个案例,但YMMV。