我正在编写一些类似于atoi()或strtoll()的字符串转换函数。我希望包含一个函数的版本,它将接受char16_t*或char32_t*,而不是只接受char*或wchar_t*。
我的函数工作得很好,但当我编写它时,我意识到我不明白char16_t或char32_t是什么。我知道标准只要求它们是至少16位或32位的整数类型,但这意味着它们是UTF-16或UTF-32。
我还知道标准定义了两个函数,但它们没有包含任何*get或*put函数(就像它们在C99中添加C99时那样)。
所以我想知道:他们希望我用char16_t和char32_t做什么?
发布于 2014-09-29 19:11:09
这是一个很好的问题,没有明显的答案。
在uchar.h中添加的C11类型和函数在很大程度上是无用的。它们只支持新类型(char16_t或char32_t)与特定于地区的、实现定义的多字节编码之间的转换,除非区域设置是基于UTF-8的,否则映射不会完成。不支持有用的转换(到/从wchar_t,到/从UTF-8)。当然,您可以将您自己的转换转到/从UTF-8,因为这些转换是由相关的RFCs/UCS/Unicode标准100%指定的,但是要小心:大多数人实现错误并且有危险的bug。
请注意,UTF-8、UTF-16和UTF-32文本的新编译器级特性(分别为u8、u和U )可能很有用;您可以使用自己的函数以完全不依赖区域设置的有意义的方式处理产生的字符串。但在我看来,在C11中对Unicode的库级支持基本上是无用的。
发布于 2014-09-29 19:51:50
测试ASCII范围内的UTF-16或UTF-32宪章是否是“通常”的10位数字之一,+或“正常”空格很容易完成,并且可以将'0'-'9'转换成数字。考虑到这一点,atoi_utf16/32()就像atoi()一样前进。一次只检查一个字符。
测试其他一些UTF-16/UTF-32是数字还是空白--这就更难了。代码需要一个扩展的isspace(), isdigit(),如果需要的区域设置可用的话,它可以切换区域设置(setlocale())。(注意:可能需要在函数完成时恢复区域设置。
将传递isdigit()但不是通常的10种字符的字符转换为它的值是有问题的。无论如何,这似乎都是不允许的。
转换步骤:
isspace()进行空白检测.your_atof()来说,转换是一种类似的方式。发布于 2016-06-05 17:25:34
这个问题可能有点老了,但我想谈谈如何用char16_t和char32_t支持实现您的函数。
最简单的方法是使用strtoull类型编写char32_t函数(称为strtoull_c32)。这使得解析unicode更容易,因为UTF-32中的每个字符都占用四个字节。然后实现strtoull_c16和strtoull_c8,在内部将UTF-8和UTF-16编码转换为UTF-32并将它们传递给strtoull_c32。
老实说,我还没有看过C11标准库中的Unicode工具,但是如果它们没有提供将这些类型转换为UTF-32的合适方法,那么您可以使用第三方库为您进行转换。
有ICU,它由IBM启动,然后被Unicode采用。这是一个功能非常丰富和稳定的图书馆,已经存在很长时间了。
我最近为C89启动了一个UTF库(UTF库),您也可以使用它。它非常简单和轻量级,单元测试和文档化。您可以尝试一下,或者使用它来了解UTF转换是如何工作的。
https://stackoverflow.com/questions/26106647
复制相似问题