char[]如何表示UTF-8字符串?

问题描述 投票:0回答:4

在 C11 中,添加了一个带有前缀

u8
的新字符串文字。这表示文本编码为 UTF-8 的字符数组。这怎么可能?普通字符不是有符号的吗?这意味着由于符号位的存在,它可以使用的信息少了一位?我的逻辑是,一串 UTF-8 文本需要是一个无符号字符数组。

c string utf-8 c11
4个回答
8
投票

普通字符不是有符号的吗?

char
signed
还是
unsigned
取决于实现。

此外,符号位并没有“丢失”,它仍然可以用来表示信息,并且

char
不一定是8位大(在某些平台上可能会更大)。


7
投票

这里有一个潜在的问题:

如果带有

CHAR_BIT == 8
的实现使用
char
的符号量值表示(因此
char
有符号),那么当UTF-8需要位模式
10000000
时,这是一个负0。所以if 该实现进一步不支持负 0,那么给定的 UTF-8 字符串可能包含无效(陷阱)值
char
,这是有问题的。即使它确实支持负零,但在
10000000
中使用 UTF-8 数据时,位模式
char
00000000
与位模式
char[]
(nul 终止符)的比较很容易导致问题.

我认为这意味着对于符号量级 C11 实现,

char
需要无符号。通常,
char
是有符号还是无符号取决于实现,但当然,如果
char
被签名导致无法正确实现UTF-8文字,那么实现者只需选择无符号即可。顺便说一句,C++ 的非 2 补码实现一直都是这种情况,因为 C++ 允许使用
char
以及
unsigned char
来访问对象表示。 C 只允许
unsigned char

在2的补码和1的补码中,UTF-8数据所需的位模式是

signed char
的有效值,因此实现可以自由地使
char
有符号或无符号,并且仍然能够表示UTF-8字符串在
char[]
。这是因为所有 256 位模式都是有效的 2 的补码值,而 UTF-8 恰好不使用字节
11111111
(1 的补码负零)。


1
投票

不,符号位还是有点!而且 UTF-8 规范本身并没有规定字符必须是无符号的。

PS Wat 是 kookwekker voor 'n naam 吗?


1
投票

char 的符号并不重要; utf8 只能通过移位和掩码操作来处理(这对于有符号类型来说可能很麻烦,但并非不可能)但是:utf8 需要至少 8 位,所以“assert (CHAR_BIT >= 8);”

举例说明:以下片段不包含对字符值的算术运算,仅包含移位和掩码。

static int eat_utf8(unsigned char *str, unsigned len, unsigned *target)
{
unsigned val = 0;
unsigned todo;

if (!len) return 0;

val = str[0];
if ((val & 0x80) == 0x00) { if (target) *target = val; return 1; }
else if ((val & 0xe0) == 0xc0) { val &= 0x1f; todo = 1; }
else if ((val & 0xf0) == 0xe0) { val &= 0x0f; todo = 2; }
else if ((val & 0xf8) == 0xf0) { val &= 0x07; todo = 3; }
else if ((val & 0xfc) == 0xf8) { val &= 0x03; todo = 4; }
else if ((val & 0xfe) == 0xfc) { val &= 0x01; todo = 5; }
else {  /* Default (Not in the spec) */
        if (target) *target = val;
        return -1; }


len--;str++;
if (todo > len) { return -todo; }

for(len=todo;todo--;) {
        /* For validity checking we should also
        ** test if ((*str & 0xc0) == 0x80) here */
        val <<= 6;
        val |= *str++ & 0x3f;
        }

if (target) *target = val;
return  1+ len;
}
© www.soinside.com 2019 - 2024. All rights reserved.