如何使用C从字符串中获取Utf-8字符?

时间:2017-04-20 08:22:20

标签: c string unicode utf-8

旧问题:How SubString,Limit Using C?,但没有人没有回答我的问题。

我想从字符串中获取一个索引。

我的字符串可能包含符号和utf-8字符。(例如:ß

对我来说,字符串的速度很重要。

1#:w_char_t数据类型对我有用吗?

2#:如何从utf-8字符串中获取字符?

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <string.h>

int main()
{
wchar_t *msg1 = L"ßC Programming";
//wprintf(L" vals> %Ls\n",msg1);
//wprintf(L" vals> %s\n",msg1);
printf(" vals> %Ls %S\n",msg1,msg1);//dont show any=====>BUG
printf(" val> %Lc\n",msg1[1]);//show `C`
printf(" val> %Lc\n",msg1[0]);//dont show any=====>BUG
printf("\n");
/////////////////////////////////
char *msg2 = "ßC Programming";
printf(" vals> %s\n",msg2);//show `ßC Programming`
printf(" val> %c\n",msg2[1]);//show `�`=====>BUG
printf(" val> %c\n",msg2[0]);//show `�`=====>BUG
printf("\n");
}

请指导我解决问题。

1 个答案:

答案 0 :(得分:1)

wchar_t可以是一个选项。但是,您应该知道它使用的编码。如果它是16位宽,使用utf-16(常见但不保证)并且您使用的代码点等于或高于0x10000(U + 10000),则再次出现同样的问题...

我个人宁愿留在普通的char。

现在的问题是,如何检测多字节字符。您可以通过查看最重要的位来发现这些:如果未设置,则您具有普通字符(ASCII兼容...),如果已设置,则该字节是多字节字符的一部分。

如果设置了第二个MSB,它也是多字节序列的起始字节,如果没有设置,则它是一个后续字节。

utf-8多字节序列的格式如下:

第一个字节:n个最高有效位设置为1指定整个序列包含多少字节,后跟一个零位。剩余的位是unicode代码点的最重要位。

每个后续字节的最高有效位为10,其余6位是代码点的下一个最高有效位。

示例字母'ß':它具有unicode代码点0xdf,二进制0b11011111。

要求8位,不适合单字节字符的七位,所以我们需要拆分它:

11 + 011111

我们总共需要两个字节,因此我们需要添加字节标题11010;然后必须用零填充第一个字节:

110 000 11 + 10 011111

所以你得到字节序列0b11000011,0b10011111(十六进制:0xc3,0x9f)。

但是,有些图书馆可以为此提供便利。例如,您可能对ICU感兴趣。