c++ string对中文字符串处理不友好的解决

中文分词的时候,发现string对中文的处理很不好,自己写了一个zhstring类,从string继承,重写了
length:返回字符数,一个汉子作为一个字符。
substr:可以正确的截取字符串
find:查找子串的位置。
上述实现的参数都是字符位置,非字节位置

顺表简单说一下中文字符在计算机中的编码。中文和英文不同,英文26个字母就能组合各种词汇,但是中文有很多汉字,因此,计算机中对中文需要编码,也就是用多个字节表示一个汉字。
计算机中中文有多种编码方式,比如ANSI编码,unicode编码。根据资料,unicode貌似只是编码方式,而不是实现方式。它有多种实现方式,比如UTF-8,UTF-16等。其中常用的UTF-8是不定长编码,也就是说字符可能只有一个字节,比如英文字符,也可能有2-4个字节,比如汉字。其中英文字符的码值和ASCII一致,都小于128.
既然汉字等字符是多字节组成的,那么诸如
string str="hello你好宝贝";
这样的字符串,想要截取“你好”两个汉字就稍微复杂一些,肯定不能用substr(5,2)这样子,因此长度2只是字节数,不是一个汉字真是的字节数,一个汉字可能2个字节,也可能4个字节。那么怎么知道汉字的实际字节数目呢?
汉字编码的第一个字节,结构必然是如:
11100xxx或者11000xxx这样子的:前面几个1,然后是0,再然后是其他码值(0或者1),最前面有几个1,表明这个汉字由几个字节组成,后面的字节都是10开头。
比如以下代码:

int main()
{
    char a[]="你好";
    string s(a);
    cout<<a<<endl;
    return 0;
}

我们在程序中用char[]存储汉字,发现某个汉字在char数组中的值是8进制的"\347",对应的二进制是"11100111",表明汉字“你”有3个字节组成,那么要截取一个汉字,就应该是(假如是字符串类型):
s.substr(0,3),少于或者多余这个字节数都会出现乱码。

怎么计算前面1的个数?方法很多,我才用的是移位运算,代码如下:

......
typedef unsigned char UBIT8;
......
    int zhstring::getBytes(UBIT8 c)
    {
        if (c < 128)
            return 1;
        int count;
        for (count = 1; count < 8; count++)
        {
            unsigned char b = c << count;
            if (b < 128)
                break;
        }
        return count;
    }

较为完整的zhstring类代码看gitee:https://gitee.com/svod5306/cpp/blob/master/中文string类/zhstring.h

原文链接: https://www.cnblogs.com/svod5306/p/14582612.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    c++ string对中文字符串处理不友好的解决

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/209058

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午11:42
下一篇 2023年2月12日 下午11:42

相关推荐