程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 萌新筆記——C++裡將string類字符串(utf-8編碼)分解成單個字(可中英混輸)

萌新筆記——C++裡將string類字符串(utf-8編碼)分解成單個字(可中英混輸)

編輯:關於C++

萌新筆記——C++裡將string類字符串(utf-8編碼)分解成單個字(可中英混輸)。本站提示廣大學習愛好者:(萌新筆記——C++裡將string類字符串(utf-8編碼)分解成單個字(可中英混輸))文章只能為提供參考,不一定能成為您想要的結果。以下是萌新筆記——C++裡將string類字符串(utf-8編碼)分解成單個字(可中英混輸)正文


  最近在建詞典,運用Trie字典樹,需求把字符串分解成單個字。由於傳入的字符串中能夠包括中文或許英文,它們的字節數並不相反。一開端天真地以為中文就是兩個字節,於是很happy地直接判別以後地位的字符的ASCII碼能否處於0~127之間,假如是就提取一個字符,否則提取兩個。在測試分字效果的時分,這種辦法出了問題。比方我傳一個“abcde一二三四五”出來,abcde可以正常分解成 a b c d e,然後面的“一二三四五”則成了亂碼。

  於是我開啟了谷歌之旅,搜索“如何在C++中將string中的中文分解成單個字”雲雲,搜索到的辦法大多與我之前的辦法相同,把代碼copy上去直接運轉也是會呈現亂碼。我忽然想到,linux下能夠會呈現中文亂碼的緣由之一就是編碼問題,於是我翻開了vim的配置文件,發現我的確是把中文設置成了utf-8。

  發現了這點之後,我專門搜索了utf-8,得知它是一種變長編碼,詳細規則如下:

  1)關於單字節的符號,字節的第一位設為0,前面7位為這個符號的unicode碼。因而關於英語字母,UTF-8編碼和ASCII碼是相反的。

  2)關於n字節的符號(n>1),第一個字節的前n位都設為1,第n+1位設為0,前面字節的前兩位一概設為10。剩下的沒有提及的二進制位,全部為這個符號的unicode碼。

  如表: 

1字節 0xxxxxxx  2字節 110xxxxx 10xxxxxx  3字節 1110xxxx 10xxxxxx 10xxxxxx 4字節 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 5字節 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 6字節 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

 

 

 

  

  

 

 

  有了這個,思緒就明晰了:首先,我要判別之後一個字是幾個字節的,然後截取相應的字節數。於是有了如下代碼:

 1 void Dictionary::splitWord(const string & word, vector<string> & characters)
 2 {
 3     int num = word.size();
 4     int i = 0;
 5     while(i < num)
 6     {
 7         int size;    
 8         if(word[i] & 0x80)
 9         {
10             if(word[i] & 0x20)
11             {
12                 if(word[i] & 0x10)
13                 {
14                     if(word[i] & 0x08)
15                     {
16                         if(word[i] & 0x04)
17                         {
18                                 size = 6;
19                         }else{
20                             size = 5;
21                         }
22                     }else{
23                         size = 4;
24                     }
25                 }else{
26                     size = 3;
27                 }
28             }else{
29                 size = 2;
30             }
31         }else{
32             size = 1;
33         }
34         string subWord;
35         subWord = word.substr(i, size);
36         characters.push_back(subWord);
37         i += size;
38     }
39 }

 

  if之中嵌套if,雖然進程很明晰,但是代碼行數也太多了,於是對其停止修正,失掉如下代碼:

 1 void Dictionary::splitWord(const string & word, vector<string> & characters)
 2 {
 3     int num = word.size();
 4     int i = 0;
 5     while(i < num)
 6     {
 7         int size = 1;
 8         if(word[i] & 0x80)
 9         {
10             char temp = word[i];
11             temp <<= 1;
12             do{
13                 temp <<= 1;
14                 ++size;
15             }while(temp & 0x80);
16         }
17         string subWord;
18         subWord = word.substr(i, size);
19         characters.push_back(subWord);
20         i += size;
21     }
22 }

 

  少了一半左右。

  分解出來的後果是存在vector容器中的,這個可以依據詳細需求停止更改。

  最後發現,中文在utf-8編碼中是三個字節的

  其實,只需求手動打印出對應string的size,就可以計算出每個字占多少字節了,事先怎樣沒發現呢?

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved