C语⾔使⽤char字符实现汉字处理
系统:windows 64
编译器:gcc version 8.1.0 (x86_64-posix-h-rev0, Built by MinGW-W64 project)
⽂本编辑器:notepad
控制台:Cmder
编程语⾔:C、Python
⾸先,要想打印汉字,必须考虑到编码问题。在windows下,由于系统使⽤GBK编码,⽽GCC解析时空手套白狼 使⽤UTF-8⽽会导致以下代码运⾏
时出现乱码:
#include
int main()
{
char一望无际的反义词 *str = "你好,世界!";
printf("%sn", str);
return 0;
}
解决⽅法为:使⽤“-fexec-chart=gbk”命令
解决了编码问题,我们还需要了解⼏点:
char类型本质上是数字,占据⼀个字节(即⼋位),可以通过%d打印编码,通过%c打印字符
在C语⾔中,⼀个汉字占据两个char类型
汉字的两个char类型为负数
在打印汉字时,它的两个char必须紧跟着
根据这⼏点,我们可以打印出汉字以及它们的编码:
#include
#include <string.h>
int main()
{
// str为字符指针,指向⼀个字符字⾯量,这个字符字⾯量由'0'结尾
char *str = "你好,世界!Hello, world残棋图片 !";
// chr为字符指针,指向str所指向的字符字⾯量的第⼀个字符的地址,即'你'字符的两个char中的第⼀个
char *chr = str;
print眼睛部位图解 f("%zu %sn", strlen(str), str);
// 如果遇到'0',说明字符串结束了
while (*chr != '0')
{
// 如果chr的编码为负数,则说明遇到了⼀个汉字
if (*chr < 0)
{
// 打印汉字及汉字的编码
// 注意两个char必须紧紧跟着打印(%c%c),否则会打印出 ??
printf("%c%c: %d%dn", *chr, *(chr+1), *(chr), *(chr+1));
// chr⾃增两个字节(因为每个汉字都由两个char组成)
chr += 2;
}
el
{
// 打印英⽂字符
printf("%c: %dn", *chr, *chr);
// chr⾃增⼀个字节
++chr;
}
}
return 0;
}
从上图,我们可以看出,这个字符串占据了25个字节,4个汉字加2个全⾓符号占据了12个字节,再加上23个英⽂字符,总共25个字
节。我们可以从下图更清晰地看出str的构造:
但是,根据我们在⽹上查询的结果,汉字‘你’的GBK编码应为:C4E3,但是在这⾥,却打印出了:-60-29,这是为什么呢?
这⾥涉及到进制的问题,可能-60-29是⼗六进制数C4E3的⼗进制数?
⾸先,我们先通过Python看看C4E3的⼆进制数以及⼗进制数。这好像跟-60-29根本不沾边。
我们先看看下⾯的代码,导⼊
#include
#include
int main()
{
printf("[%d ~ %d我的拿手好菜 ]n", CHAR_MIN, CHAR_MAX);
printf("%c%cn", 0xC4, 0xE3);return 0;
}
我们可以看到:char类型的取值范围为[-128 ~ 127],但社团申请表 是我们却可以打印出汉字”你“。这是为什么呢?明明char的取值范围最多127,
⽽汉字“你”的两个字符分别为:196和227,都超过了这个值。其实这是因为,C语⾔将这两个数字的⼆进制数作为负数处理。C中的char类
型有1个字节,占8位,⽽它的最⾼位为符号位,当它为0时为正,1时则为负。C通过对正数做补码操作得到负数。补码,即对⼀个⼆进制数
取反,然后再加1。⽐如,0xC4的⼆进制数为0b11000100,我们可以看到最⾼位1,在C中这个数就是负数。我们可以通过对这个⼆进制数
做补码操作,得到0b00111100,即60。所以0b11000100在C中表⽰为-60。
从以上,我们可以发现,GBK编码中,⼀个汉字占两字节。因为C中char类型只占⼀个字节,所以需要使⽤两个char类型来表⽰汉字。
因为C中char为有符号类型,char的表⽰范围为[-128 ~ 127],所以在遇到⼤于127的数字时,会被char表⽰为负数。
其实,我们还可以使⽤unsigned char来实现。char默认是有符号的,取值范围为:-128 ~127。⽽unsigned char的取值范围则为:
0~255,那么汉字“你”的编码就会被显⽰为:196和227。
#include
#include <string.h>
int main()
{
// str为字符指针,指向⼀个字符字⾯量,这个字符字⾯量由'0'结尾
unsigned char *str = (unsigned char *)"你好,世界!Hello, world!";
// chr为字符指针,指向str所指向的字符字⾯量的第⼀个字符的地址,即'你'字符的两个char中的第⼀个
unsigned char *chr = str;
printf("%zu %sn", strlen(str), str);
// 如果遇到'0',说明字符串结束了
while (*chr != '0')
{
// 如果chr的编码⼤于127,则说明遇到了⼀个汉字
if (*chr > 127)
{
// 打印汉字及汉字的编码
// 注意两个char必须紧紧跟着打印(%c%c),否则会打印出 ??
printf("%c%c: %d %dn", *chr, *(chr+1), *(chr), *(chr+1));
// chr⾃增两个字节(因为每个汉字都由两个char组成)
chr += 2;
}
el
{
// 打印英⽂字符
printf("%c: %dn", *chr, *chr);
// chr⾃增⼀个字节
++chr;
}
}
return 0;
}
本文发布于:2023-04-21 05:26:42,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/fan/89/840559.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |