看到BaiDu的笔试题一道。
已知一个字串由GBK汉字和ansi编码的数字字母混合组成,编写C语言函数实现从中去掉所有ansi编码的的数字和字母
(包括大小写),要求在原字串上返回结果。
函数接口为: int filter_ansi( char * gbk_string)。
注:汉字的GBK编码范围是 0x8140 - 0xFEFE 。
(包括大小写),要求在原字串上返回结果。
函数接口为: 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 ;
}
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 )。
16 - 55区为一级汉字,按拼音排序。
56 - 87区为二级汉字,按部首 / 笔画排序。
每个汉字及符号以两个字节来表示。第一个字节称为“高位字节”,第二个字节称为“低位字节”。
“高位字节”使用了0xA1 - 0xF7 (把01 - 87区的区号加上0xA0),“低位字节”使用了0xA1 - 0xFE (把01 - 94加上0xA0)。
例如“啊”字在大多数程序中,会以0xB0A1储存。(与区位码对比: 0xB0 = 0xA0 + 16 , 0xA1 = 0xA0 + 1 )。