关于GBK编码及C语言中文输出问题
引入
在使用C语言进行输出时,我们可以发现汉字是占两个字节的,如果想打印出汉字需要连续打印两个字节,如果仅仅打印一个汉字字节会出现输出为空的情况。如此情况的产生是因为汉字的编码关系。目前应用最为灵活的utf-8,在很多编译器中并不是默认的编码方式,乃至我们的电脑中,选择中文区域后我们的汉字编码为GBK编码。
GB2312及GBK编码
GB2312是我国的第一种汉字编码。尽管ASCII 码成功的对西方字符编码的标准进行了统一,但作为7位编码,表示范围有限(0~127),就算是8位ASCII 码,高位的128个字符作为扩展,也都是用来存放英文的制表符,部分音标字符等其它符号。常用的汉字有几千个,为了解决汉字编码问题,GB2312应运而生。
GB2312采用区位码进行设计,将编码表分为94个区,每个区94个位,每个位放置1个字符。即使用双字节对一个汉字进行编址,前一个字节代表这个汉字在编码表的区号,后一个字节代表这个汉字在区中的位号。一般编码方式为0xA0 + 区号,0xA0 + 位号,汉字的编码范围是0xB0A1~0xF7FE
在区号中01-09是符号区,16-87是汉字区,10-15及88-94是未定义的空白区。
GB2312满足了基本的汉字编码需要,但未收录繁体字和生僻字,为了更好处理人名和古汉语,GBK横空出世,是GB2312的超集,相同字符编码相同,收录字符更多,更广。
这里提供汉字与国际码转换查询网:https://www.qqxiuzi.cn/bianma/guobiaoma.php
正确输出及中文判断
这里以汉字【加】为例,对应编码为:
根据前文介绍,BC为区号,D3为位号。转换为对应的十进制:BC(188) D3(211)
当我们把两个字符连续打印时,如果第一个字符是数值大于ASCII码的最高范围127,则会将其视为其它编码格式,在正确的区位号下,编译器识别其为GBK,从而输出汉字。
如上图所示,字符数值符合ASCII码范围,则按照ASCII码进行解析。
当我们将中文字符编码分开输出时,由于字符数值高于ASCII码又违背了GBK编码双字节的编码规则,此时无法正常输出。
如何判断是否为中文字符
需求:输入一串文字,将文字中的半角字符剔除,将全角字符输出
【全角】:一个字符占两个字节
【半角】:一个字符占一个字节
根据需求,可以发现我们需要的是将汉字输出,其它剔除。上文提到,汉字的区号是0xA0 + 区号,因此只要第一个字符大于0xA0,此时顺序输出下一个字符即可。
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
// @名称:is2byte函数
// @用途:判断是否为全角文字的第一个字节
int is2byte(int ch){
if(ch > 0xa0){
return TRUE; /*2字节文字(全角)*/
}
else
return FALSE; /*1字节文字(半角)*/
}
int main(){
int ch;
while((ch = getchar())!=EOF){
if(is2byte(ch) == TRUE){
putchar(ch);
putchar(getchar());
}
}
return 0;
}
此篇博客是博主在遇到问题,搜索资料后的简单记录,博主才疏学浅,如果博文出现错误请及时指出,也请各位谅解!