C 为什么U+的UTF-8编码为2字节;1xxxx字符?
我试图弄清楚C如何处理Unicode中的字符代码。我将语言环境设置为LC_ALL“fr_CA.UTF8”,然后用C 为什么U+的UTF-8编码为2字节;1xxxx字符?,c,unicode,utf-8,C,Unicode,Utf 8,我试图弄清楚C如何处理Unicode中的字符代码。我将语言环境设置为LC_ALL“fr_CA.UTF8”,然后用wscanf()输入一个字符(作为wchar\u t的数组)。然后我探索每个字节,发现一些奇怪的东西。我输入了一个高音键(“如果您正确地打印了构成wchar\u t值的字节,或者如果您只是跳过它,并且在不尝试将其拆分为字节的情况下打印它们的值,您将看到您期望的结果: wprintf(L"%x\n", (int)input[0]); wprintf(L"%x\n", (int)input
wscanf()
输入一个字符(作为wchar\u t
的数组)。然后我探索每个字节,发现一些奇怪的东西。我输入了一个高音键(“如果您正确地打印了构成wchar\u t
值的字节,或者如果您只是跳过它,并且在不尝试将其拆分为字节的情况下打印它们的值,您将看到您期望的结果:
wprintf(L"%x\n", (int)input[0]);
wprintf(L"%x\n", (int)input[1]);
其结果是:
1d11e
0
您尝试这样做的方式表明,您错误地认为wchar\u t
值是16位的,并且存在“多wchar\u t
-字符”这样的东西。C语言非常明确地表示没有这样的东西。使用16位wchar\u t
的实现是错误的(或者至少不能在BMP之外支持Unicode)。当然,一个相当流行的版本是大错特错的
我刚刚注意到您在问题的标题中也提到了UTF-8,但内容与UTF-8表示无关。
wchar\u t
是(通常;不完全是必需的)Unicode代码点编号,相当于UCS-4(或仅支持BMP的实现中的UCS-2)。而语言环境的多字节编码几乎肯定必须是UTF-8才能访问该字符(尽管GB18030也可以使用),如果将所有流作为宽字符流处理,则不会显示UTF-8。如果正确打印了构成wchar\t
值的字节,或者如果您只是跳过该操作并打印了它们的值,而没有尝试将其拆分为字节,您将看到预期结果:
wprintf(L"%x\n", (int)input[0]);
wprintf(L"%x\n", (int)input[1]);
其结果是:
1d11e
0
您尝试这样做的方式表明,您错误地认为wchar\u t
值是16位的,并且存在“多wchar\u t
-字符”这样的东西。C语言非常明确地表示没有这样的东西。使用16位wchar\u t
的实现是错误的(或者至少不能在BMP之外支持Unicode)。当然,一个相当流行的版本是大错特错的
我刚刚注意到您在问题的标题中也提到了UTF-8,但内容与UTF-8表示无关。
wchar\u t
是(通常;不完全是必需的)Unicode代码点编号,相当于UCS-4(或仅支持BMP的实现中的UCS-2)。而语言环境的多字节编码几乎肯定必须是UTF-8才能访问该字符(尽管GB18030也可以使用),如果将所有流作为宽字符流处理,UTF-8将不会出现。是否有第三个字节没有打印?输出,所以首先要做的是确定wchar\u t的大小。呃…@ikegami,似乎你是对的。@nyrguds我知道数据位之间有控制位。Could可能还有第三个字节没有打印?输出所以首先要做的是确定wchar\u t的大小。呃…@ikegami似乎你是对的。@nyrguds我知道数据位中有控制位。在BMP之外,re“不支持Unicode”,除非他们使用代理。例如,JavaScript就是这样做的。我猜“一个非常流行的”这就是为什么我不明白的原因。wchar\u t
在Linux上是32位的,在Windows上是16位的。所以,如果我理解正确的话,在Linux上用2wchar\u t
来表示字符串,在Windows上用3来表示字符串,因为代码点会扩展到16位以上…?但在Linux上是64位,在Windows上是48位…@ikegami:那是C的wchar\u t
和相关接口不可能,因为它们的工作方式。mbrtowc
无法为一个多字节字符输出两个wchar\u t
值(这是基本的,不允许),而isw*
函数无法报告“多wchar\u t
字符”的属性(对于某些用户来说,这可能是一个可接受的限制)。因此,不,将wchar\u t
用作UTF-16是无法解决的(Windows尝试这样做,但破坏了标准C函数,让您使用自己的东西);它确实与该语言不兼容。Re“无法在BMP之外支持Unicode”,除非他们使用代理。例如,JavaScript就是这样做的。我猜“一个非常流行的”这就是为什么我不明白的原因。wchar\u t
在Linux上是32位的,在Windows上是16位的。所以,如果我理解正确的话,在Linux上用2wchar\u t
来表示字符串,在Windows上用3来表示字符串,因为代码点会扩展到16位以上…?但在Linux上是64位,在Windows上是48位…@ikegami:那是C的wchar\u t
和相关接口不可能,因为它们的工作方式。mbrtowc
无法为一个多字节字符输出两个wchar\u t
值(这是基本的,不允许),而isw*
函数无法报告“多wchar\u t
字符”的属性(对于某些用户来说,这可能是一个可接受的限制)。因此,不,将wchar\u t
用作UTF-16是无法解决的(Windows尝试这样做,但破坏了标准C函数,让您使用自己的东西);它确实与该语言不兼容。