【问题标题】:How Get a Utf-8 Char from String Using C?如何使用 C 从字符串中获取 Utf-8 字符?
【发布时间】:2017-09-16 18:19:11
【问题描述】:

老问题: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");
}

请指导我解决问题。

【问题讨论】:

    标签: c string unicode utf-8


    【解决方案1】:

    wchar_t 可以是一个选项。不过,您应该了解它使用的编码。如果它是 16 位宽,使用 utf-16(常见,但不保证)并且您使用的代码点等于或高于 0x10000 (U+10000),那么您又遇到了同样的问题...

    不过,我个人更愿意使用普通字符。

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

    如果也设置了第二个MSB,则为多字节序列的起始字节,如果不设置,则为后续字节。

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

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

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

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

    需要8位,单字节字符不适合7位,所以需要拆分:

    11 + 011111
    

    我们一共需要两个字节,所以我们需要添加字节头11010;然后必须用零填充第一个字节:

    110 000 11 + 10 011111
    

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

    不过,有一些图书馆促进了这一点。例如,您可能对ICU 感兴趣。

    【讨论】:

    • ICU 是 C 的库吗?
    • @GoWorkCode 引用他们的网站:“ICU 是一套成熟的、广泛使用的 C/C++ 和 Java 库,为软件应用程序提供 Unicode 和全球化支持。”
    • 树莓派微控制器和Windows支持?
    • 没有 ICU 无法获取 utf-8 字符?但是许多没有 lib 的项目都会这样做!
    • 关于 C 支持:icu-project.org/apiref/icu4c。微控制器,您需要检查自己(您可能只是尝试从源代码编译库),Windows 支持是(“对于 Microsoft Visual Studio,/utf-8 选项设置在 ICU 的 .vcxproj 文件中。”)。 ICU只是一个帮手,如果您不想或不能使用它,您仍然可以按照我在回答中的描述手动分解utf...
    猜你喜欢
    • 1970-01-01
    • 2017-03-04
    • 2014-02-22
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多