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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM