C11 Unicode支持

时间:2014-09-29 18:42:17

标签: c unicode c11

我正在编写一些类似于atoi()strtoll()的字符串转换函数。我想要包含一个我的函数版本,它接受char16_t *或char32_t *而不仅仅是char *或wchar_t *。

我的功能很好,但正如我写的那样,我意识到我不明白char16_t或char32_t是什么。我知道标准只要求它们分别是至少16或32位的整数类型,但这意味着它们是UTF-16或UTF-32。

我也知道标准定义了几个函数,但它们没有包含任何* get或* put函数(就像它们在C99中wchar.h中添加时那样)。

所以我想知道:他们希望我对char16_t和char32_t做些什么?

3 个答案:

答案 0 :(得分:9)

这是一个很好的问题,没有明显的答案。

C11中添加的uchar.h类型和功能基本上没用。它们仅支持新类型(char16_tchar32_t)与特定于语言环境的实现定义的多字节编码之间的转换,除非语言环境基于UTF-8,否则这些映射不会完整。不支持有用的转换(来自wchar_t,来自/来自UTF-8)。当然,您可以自行转换为UTF-8的转换,因为这些转换是由相关的RFC / UCS / Unicode标准100%指定的,但要小心:大多数人错误地实现它们并且有危险的错误。

请注意,UTF-8,UTF-16和UTF-32文字(u8u和{{1}的新编译器级功能分别)可能有用;您可以使用自己的函数处理生成的字符串,这些函数完全取决于区域设置。但是,在我看来,C11中的库级对Unicode的支持基本没用。

答案 1 :(得分:3)

测试ASCII范围内的UTF-16或UTF-32章程是否是“通常”10位数之一,+, - 或“普通”白色空间很容易做到以及转换{{1一个数字。鉴于此,'0'-'9'就像atoi_utf16/32()一样。只需一次检查一个角色。

测试一些其他 UTF-16 / UTF-32是数字还是空白 - 这更难。代码需要一个扩展的atoi(),如果需要的语言环境可用,可以切换语言环境(isspace(), isdigit())。 (注意:当函数完成时,可能需要恢复语言环境。

将通过setlocale()但不是通常的10个字符的字符转换为其值是有问题的。无论如何,出现甚至不被允许。

转换步骤:

  1. 将区域设置设置为UTF-16 / UTF-32的相应区域。

  2. 使用isdigit()进行空白区域检测。

  3. 转换与isspace()类似。

  4. 恢复本地。

答案 2 :(得分:0)

这个问题可能有点陈旧,但我想通过char16_tchar32_t支持来实现您的功能。

最简单的方法是使用strtoull类型编写char32_t函数(称之为strtoull_c32)。这使得解析unicode更容易,因为UTF-32中的每个字符占用四个字节。然后通过将strtoull_c16strtoull_c8编码内部转换为UTF-8并将其传递给UTF-16来实施UTF-32strtoull_c32

老实说,我没有看过C11标准库中的Unicode工具,但是如果它们没有提供将这些类型转换为UTF-32的合适方式,那么你可以使用第三方库来制作转换给你。

ICU,由IBM启动,然后由Unicode Consortium采用。它是一个功能丰富且稳定的库,已经存在了很长时间。

我最近为C89创建了一个UTF库(UTFX),您也可以使用它。它非常简单,重量轻,经过单元测试和记录。您可以放弃,或者使用它来了解有关UTF转换如何工作的更多信息。