C++判断字符串中是否有中文

参考:

http://baike.baidu.com/view/391899.htm?fr=aladdin

http://baike.baidu.com/view/1204863.htm

http://baike.baidu.com/view/40801.htm?fr=aladdin

http://baike.baidu.com/subview/185282/6215666.htm?fr=aladdin

http://bbs.csdn.net/topics/300045872

http://bbs.chinaunix.net/thread-1237260-1-1.html

http://bbs.csdn.net/topics/290003569

http://tieba.baidu.com/p/1731917689

http://bbs.csdn.net/topics/360228774

GB2312编码表:http://wenku.baidu.com/link?url=p86K97LL1MPih8Iz73iYJsNfyDrHPFXn_63f-MMdrsLf5lgL-1wWBOJjbbm0N9AI8Qe1sl3cNzwRqGQJWO4seiiSH6bRY5ENDpbOFdh28Tu

输入的字符串编码是什么?

Unicode/GBK/gb2312/gb18030/UTF-8

不知道编码来判断是不是中文,只能是猜,不能完全给出正确结果.
这个就是编码的自动识别了,只有先识别了是什么编码的文本,才能针对性的去判断是否为中文。

基本思路是

1.判断当前文本的编码

2.判断出来后,读入字符串中并把它统一转换成unicode或者utf-8的字符串。

3.根据unicode或者utf-8的编码中中文字符的编码范围来判断每个字符是不是中文。


这里面最难的是第一条,这个最成功的典范是ie,firefox这些浏览器中编码识别的实现。基本思路是猜,因为BOM是可以改的,甚至可以没有。

因此靠bom等来识别编码是错误的思路。。只能是猜,基于某种算法来猜,只要算法合理则基本上不会出错,但不可能是100%,你看有时候ie看网页

不是也会乱码啊,那就是猜错了。。。

因为firefox是开源的,所以判断编码的源代码在网上有下的,你找找看。




分析一下:

问题:用C++判断字符串是否为中文
简化:判断字符串是否为中文
这个问题本身就有问题.你们谁能说他有本事判断给定的字符串是否为中文?
首先 
中文是一中编码,而UNICODE是一种格式.
编码是要表示实际东西的,而UNICODE是一种传输用的方式;
如果说编码是犯人,0001代表某某,那么UNICODE就是犯人带的刑具
一个带了刑具的犯人,你咋知道他是那个国家那种级别的罪犯呢???
其次
对于提问者,首先你要告诉别人你的字串是UNICODE的还是ANSI的.
因为网络传输的是一堆数据,比如文件,他们都在开始的信息里标识了是UNICODE还是普通的ANSI
你一个单独的字串,没有标识,你不说明,能知道是UNICODE还是ANSI的人肯定是江湖骗子
再次

即使知道是UNICODE的串,也要去掉伪装,还原成ANSI才能判断的.

如果是UNICODE的
先转ANSI再判断

处理完成了需要用UNICODE的
在重新转ANSI就行了

就象IP包一样
接收-->解析-->处理--打包-->发送


这个时候的判断也很简单
GB2312中文的表示是用两个字节,都大于0xa1;
取得一个字节,如果大于0xa1,再取一个字节,如果还大于0xa1,就是汉字
char  *kk="adjg竟关千5667六爱123\0";
char  *p=kk;
while(*p)
{
   if((*(p+1)==NULL)||*p<0xa1||*(p+1)<0xa1)
   {
       //独1字节或连续两字节有一个<0xa1,肯定不是汉字
       //当普通字符处理
       p++;
   }
   else
   {
       //处理汉字
       p+=2;
   }

}

在GB2312编码中,高字节和低字节的编码范围都是0xa1-0xfe ,而第一个字节大于0xa1的未必就是汉字,汉字的取值范围应该是从0xb0a1至0xf7fe。

int main()
{

    string str = ",在过几天,我就要看完《C++程序设计》这本书了;心里很激动!想放松放松。";
    size_t n=0;
    size_t count=0;
    unsigned char c1,c2;
    setlocale(LC_ALL,"");
    while(n<str.size()-1)
    {
        count=mblen(&str[n],2);
        if (count==1) 
            str.erase(n,1);//earse函数的使用:删除从index索引开始的num个字符, 返回*this.
        else
        {
            c1=(unsigned char)str[n];
            c2=(unsigned char)str[n+1]; //这段程序是根据GB2312编码来的,下面的范围都是其中非汉字的编码范围,可以查看相应的编码表
            if (((c1>=0xa1&&c1<=0xa9)&&(c2>=0xa1&&c2<=0xfe))||
                ((c1>=0xa8&&c1<=0xa9)&&(c2>=0x40&&c2<=0xa0)))
                str.erase(n,2);
            else
                n++;
        }
    }
    
    system("pause");
    return 0;

}

运行结果:



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值