5

刚才我正在尝试在我的 c 程序中使用 libunistring。我必须处理 UTF-8 字符串,为此我使用了 libunistring 库中的 u8_strlen() 函数。
代码示例:

void print_length(uint8_t *msg) {
    printf("Default strlen: %d\n", strlen((char *)msg));
    printf("U8 strlen: %d\n", u8_strlen(msg));
}

想象一下我们print_length()msg = "привет"(西里尔文,utf-8 编码)调用。我预计strlen()应该返回 12(6 个字母 * 每个字母 2 个字节),并且 u8_strlen()应该返回 6(只有 6 个字母)。

但我收到了奇怪的结果:

Default strlen: 12
U8 strlen: 12

在此之后,我尝试查找 u8_strlen 实现,并找到了以下代码:

size_t
u8_strlen (const uint8_t *s)
{
    return strlen ((const char *) s);
}

我想知道,这是错误还是正确答案?如果正确,为什么?

4

2 回答 2

7

我相信这是预期的行为。

libunistring 手册说:

size_t u8_strlen (const uint8_t *s)

返回 s 中的单位数。

同样在手册中,它定义了这个“单位”是什么:

UTF-8 字符串,通过类型 'uint8_t *'。单位是字节(uint8_t)。

我相信他们标记该函数的原因,u8_strlen即使它只是标准strlen,是该库还分别具有u16_strlenu32_strlen用于 UTF-16 和 UTF-32 字符串的操作(这将计算 2 字节单元的数量,直到 0x0000 , 和 4 字节单元,直到 0x00000000),它们u8_strlen只是为了完整性而包括在内。

然而, GNU gnulib确实包含mbslen了可能做你想做的事:

mbslen 函数:确定字符串中多字节字符的个数。

于 2013-09-26T16:25:47.963 回答
0

除了 Berry 的回答,我注意到 C 标准允许 char 中有超过 8 位。然后strlen()将返回 char 中的长度,而不是 8 位块,因此将是返回值的一小部分u8_strlen()(或应该返回 - 您显示的实现显然不起作用并给出与 相同的答案strlen())。

于 2013-09-26T18:35:55.490 回答