过滤非GBK字符
看到BaiDu的笔试题一道。
已知一个字串由GBK汉字和ansi编码的数字字母混合组成,编写C语言函数实现从中去掉所有ansi编码的的数字和字母
(包括大小写),要求在原字串上返回结果。
函数接口为:int filter_ansi(char* gbk_string)。
注:汉字的GBK编码范围是 0x8140 - 0xFEFE。
其实这题的思想与 在字符串中删除特定的字符 类似,事实上还要简单,因为没有过滤规则(参考博文后一个参数可以看成是过滤规则)。
汉字编码常用的有GBK和GB2312,一般用双字表示,为了区分ansi编码,其最高位一般为1。
下面写成代码如下
#include <stdio.h>
int del_ansic(char *gbk)
{
char *first = gbk;
char *last = gbk;
while(*last)
{
//如果是汉字,双字节高字节为1
if((*last &0x80))
{
*first++ = *last++;
*first++ = *last++;
}else
++last;
}
*first = '\0';
}
int main()
{
char gbk_str[]="汉字bak博大精深supername所以要淡ter百度";
del_ansic(gbk_str);
printf("gbk %s\n",gbk_str);
return 0;
}
但是该代码对于某些处于无效,比如"淡定s",无法转换,测试估计的"定"的编码有问题。有兴趣的同学可以试试题设中给出的GBK编码范围。添加一个ch变量测试下范围即可。
下面是GBK2312的资料。
01-09区为特殊符号。
16-55区为一级汉字,按拼音排序。
56-87区为二级汉字,按部首/笔画排序。
每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”,第二个字节称为“低位字节”。
“高位字节”使用了0xA1-0xF7(把01-87区的区号加上0xA0),“低位字节”使用了0xA1-0xFE(把01-94加上0xA0)。
例如“啊”字在大多数程序中,会以0xB0A1储存。(与区位码对比:0xB0=0xA0+16,0xA1=0xA0+1)。