鱼C论坛

 找回密码
 立即注册
查看: 887|回复: 7

[已解决]关于中文字符的问题

[复制链接]
发表于 2023-7-22 21:44:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
有大佬能解释一下
中文字符的UTF-8编码的第一个字节的前三位是 1110,即大于等于224
是什么意思吗
#include <stdio.h>
#include <stdlib.h>
#define MAX 1024

int is_utf8_chinese(char ch) {
    // 判断是否为中文字符,中文字符的UTF-8编码范围是三个字节
    // 中文字符的UTF-8编码的第一个字节的前三位是 1110,即大于等于224
    return ((unsigned char)ch >= 224);
}

int main()
{
    char str[MAX];
    char *target = str;
    char ch;
    int length = 0;

    printf("请输入一个字符串:");
    fgets(str, MAX, stdin);

    while (1)
    {
        ch = *target++;
        if (ch == '\0')
        {
            break;
        }
        if (is_utf8_chinese(ch))
        {
            target += 2; // 中文字符占用3个字节,所以移动指针2位
        }
        length++;
    }

    printf("您总共输入了 %d 个字符!\n", length - 1);
    system("pause");
    return 0;
}
最佳答案
2023-7-22 21:45:02
在UTF-8编码中,单个字节的数据表示方式分别为:

· 对于ASCII码(0-127),UTF-8编码用一个字节表示,字节的最高位是0。
· 对于128到2047之间的字符,UTF-8编码用两个字节表示,字节的最高位是110和10。
· 对于2048到65535之间的字符,UTF-8编码用三个字节表示,字节的最高位是1110和10。

因此,“中文字符的UTF-8编码的第一个字节的前三位是 1110,即大于等于224”这句话,是因为在UTF-8编码中,中文字符的编码是用三个字节表示的,这三个字节的最高位是1110和10。当然,还需要注意的是,这个函数只检查了第一个字节是不是中文字符的开始字节,而没有检查后续的字节。

在您的代码中, is_utf8_chinese(char ch) 函数接收一个字符,将其转换为无符号字符,然后检查该字符是否大于等于224。如果是,那么它假设这个字符是UTF-8编码的中文字符的开始。这种方法可以在大多数情况下工作,但它不能保证字符确实是中文,因为其它一些非中文字符的UTF-8编码的第一个字节也可能大于等于224。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-7-22 21:44:47 | 显示全部楼层
关于中文字符的UTF-8编码的第一个字节前三位为1110的意思

UTF-8是一种变长字符编码方案,用于表示Unicode字符集中的字符。对于多字节的字符,在UTF-8编码中,第一个字节的前面会有一些特定的标志位来指示该字符的长度。

在UTF-8编码中,用来表示三字节字符(如中文字符)的第一个字节的前三位是固定的,为"1110"。这表示该字符由三个字节组成。具体的编码格式如下:

[/code]
| 0xE0 - 0xEF | 0x80 - 0xBF | 0x80 - 0xBF |
|--------------|--------------|--------------|
|   1110xxxx   |   10xxxxxx   |   10xxxxxx   |
[/code]

其中,"x"代表实际字符的编码位。

所以,当我们判断一个字节是否为中文字符时,如果它的最高三位是"1110",则可以认为它是中文字符的第一个字节。

在给出的示例代码中,is_utf8_chinese 函数就是用来判断一个字符是否为中文字符。它通过将字符转换为无符号字符,并与224(即0xE0)进行比较,判断其最高三位是否为"1110",以判断是否为中文字符。

希望对你有所帮助!如果还有其他问题,请随时提问。

球一个最佳答案谢谢啦!这对我非常重要!

评分

参与人数 1荣誉 +3 贡献 +1 收起 理由
1613551 + 3 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-22 21:45:02 | 显示全部楼层    本楼为最佳答案   
在UTF-8编码中,单个字节的数据表示方式分别为:

· 对于ASCII码(0-127),UTF-8编码用一个字节表示,字节的最高位是0。
· 对于128到2047之间的字符,UTF-8编码用两个字节表示,字节的最高位是110和10。
· 对于2048到65535之间的字符,UTF-8编码用三个字节表示,字节的最高位是1110和10。

因此,“中文字符的UTF-8编码的第一个字节的前三位是 1110,即大于等于224”这句话,是因为在UTF-8编码中,中文字符的编码是用三个字节表示的,这三个字节的最高位是1110和10。当然,还需要注意的是,这个函数只检查了第一个字节是不是中文字符的开始字节,而没有检查后续的字节。

在您的代码中, is_utf8_chinese(char ch) 函数接收一个字符,将其转换为无符号字符,然后检查该字符是否大于等于224。如果是,那么它假设这个字符是UTF-8编码的中文字符的开始。这种方法可以在大多数情况下工作,但它不能保证字符确实是中文,因为其它一些非中文字符的UTF-8编码的第一个字节也可能大于等于224。

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
1613551 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-22 21:46:03 | 显示全部楼层
这个代码是统计有多少个中文字符以及中英文混合字符的程序
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-22 22:00:04 | 显示全部楼层
isdkz 发表于 2023-7-22 21:45
在UTF-8编码中,单个字节的数据表示方式分别为:

· 对于ASCII码(0-127),UTF-8编码用一个字节表示, ...

其实我不是很懂为什么还要转成无符号字符
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-22 22:08:47 | 显示全部楼层
1613551 发表于 2023-7-22 22:00
其实我不是很懂为什么还要转成无符号字符

因为字符编码的序号就是没有负的

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
1613551 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-7-24 19:51:49 | 显示全部楼层
isdkz 发表于 2023-7-22 22:08
因为字符编码的序号就是没有负的

我还有一点疑惑,为什么是大于224,224是怎么得出来的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-24 21:05:35 | 显示全部楼层
1613551 发表于 2023-7-24 19:51
我还有一点疑惑,为什么是大于224,224是怎么得出来的

UTF-8编码是一种可变长度的编码方式,可以使用1到4个字节表示一个字符。为了在字符中表示这种长度的变化,UTF-8编码使用特殊的位模式。

在UTF-8编码中,一个字节的前几个位被用来表示编码的长度:

· 如果第一个字节的开头是0,那么这个字符只有一个字节,也就是说这个字符在ASCII表中。
· 如果第一个字节的开头是110,那么这个字符有两个字节。
· 如果第一个字节的开头是1110,那么这个字符有三个字节。
· 如果第一个字节的开头是11110,那么这个字符有四个字节。

这里的 "224" 是二进制 "11100000" 在十进制下的表示。也就是说,如果一个字节的值大于等于224,那么它的二进制表示至少是 "1110xxxx",这意味着这个字符是一个三字节的字符。

这种设计让计算机能够很容易地确定一个字符的长度,不管它是在字符串的开始、中间,还是结束。这就是UTF-8编码方式的一个重要特性。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-7 11:21

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表