假设只有 C99标准 这篇论文,需要根据该标准来实现
C99 标准(7.19.6.1)中对于
如果没有指定 l 长度修饰符,参数应为字符类型数组的初始元素的指针。从数组中写入字符直到(但不包括)终止空字符。如果指定了精度,则最多只写入那么多字节。如果未指定精度或精度大于数组大小,则该数组应包含空字符。
如果存在 l 长度修饰符,则参数应为 wchar_t 类型数组的初始元素的指针。从数组中转换宽字符为多字节字符(每个字符都像调用 wcrtomb 函数一样,使用 mbstate_t 对象描述的转换状态,在第一个宽字符转换之前初始化为零),直到包括终止空宽字符为止。将生成的多字节字符写入到(但不包括)终止空字符(字节)。如果未指定精度,则该数组应包含空宽字符。如果指定了精度,则最多只写入那么多字节(包括移位序列,如果有的话),如果函数需要访问数组末尾后面的宽字符才能等于精度给出的多字节字符序列长度,则该数组应包含空宽字符。在任何情况下都不会写入部分多字节字符。
我不太理解这段话的总体意思,尤其是“如果指定了精度,则最多只能写入那么多字节”的陈述。
例如,我们拿UTF-16字符串“TEST”(字节序列:0x54、0x00、0x45、0x00、0x53、0x00、0x54、0x00)来举例。
在以下情况下,预期将写入输出缓冲区的内容是什么:
- 如果精度为3 - 如果精度为9(比字符串长度多一个字节) - 如果精度为12(比字符串长度多几个字节)
然后还有“从数组中读取的宽字符将转换为多字节字符”。这是否意味着UTF-16应该先转换为UTF-8?如果我只想使用UTF-16,那么这很奇怪。
printf
库函数以便使用 UTF-16 编码。请问,当指定精度时,s
转换的期望行为是什么?C99 标准(7.19.6.1)中对于
s
转换的说明如下:如果没有指定 l 长度修饰符,参数应为字符类型数组的初始元素的指针。从数组中写入字符直到(但不包括)终止空字符。如果指定了精度,则最多只写入那么多字节。如果未指定精度或精度大于数组大小,则该数组应包含空字符。
如果存在 l 长度修饰符,则参数应为 wchar_t 类型数组的初始元素的指针。从数组中转换宽字符为多字节字符(每个字符都像调用 wcrtomb 函数一样,使用 mbstate_t 对象描述的转换状态,在第一个宽字符转换之前初始化为零),直到包括终止空宽字符为止。将生成的多字节字符写入到(但不包括)终止空字符(字节)。如果未指定精度,则该数组应包含空宽字符。如果指定了精度,则最多只写入那么多字节(包括移位序列,如果有的话),如果函数需要访问数组末尾后面的宽字符才能等于精度给出的多字节字符序列长度,则该数组应包含空宽字符。在任何情况下都不会写入部分多字节字符。
我不太理解这段话的总体意思,尤其是“如果指定了精度,则最多只能写入那么多字节”的陈述。
例如,我们拿UTF-16字符串“TEST”(字节序列:0x54、0x00、0x45、0x00、0x53、0x00、0x54、0x00)来举例。
在以下情况下,预期将写入输出缓冲区的内容是什么:
- 如果精度为3 - 如果精度为9(比字符串长度多一个字节) - 如果精度为12(比字符串长度多几个字节)
然后还有“从数组中读取的宽字符将转换为多字节字符”。这是否意味着UTF-16应该先转换为UTF-8?如果我只想使用UTF-16,那么这很奇怪。
%s
接受一个字符串。由于所有的空字节,你不能在 C 字符串中存储 UTF-16。(此外,UTF-16 不是一个字符集,而是一种编码方式。) - melpomeneT
。 - melpomene%ls
/wchar_t
吗? - melpomeneCHAR_BIT
的值是多少?如果CHAR_BIT == 8
,那么你无法使用%s
处理UTF-16;你需要使用%ls
,并将wchar_t *
作为相应的参数传递。然后你需要阅读规范的第二段。如果CHAR_BIT == 16
,那么数据中不能有奇数个八位字节。接下来,你需要了解wchar_t
与char
的关系(它们的大小是否相同?是否具有相同的符号性?),并解释两个段落以得出统一的效果 —— 除非你决定让wchar_t
表示UTF-32。 - Jonathan Leffler