GBK中文編碼和std::string的衝突問題

最近寫了一個按照分隔符拆分字符串的接口,
void PickUp(std::string &strDes,std::vector<std::string>

&vecData,const std::string sign=";" )
{
 std::string::size_type fpos=0,bpos=0;
 std::string strTemp;
 while(bpos != std::string::npos && strDes.size())
 {
  bpos = strDes.find(sign,fpos);
  strTemp = strDes.substr (fpos,bpos-fpos);
  vecData.push_back (strTemp);
  fpos = bpos+1;
 }
}
開始用得挺舒服沒有出現問題,但是後來出現了一個新的需求又用到這個接口,但是分隔符不再是默認的";",而是換成了下劃線"_"。這時問題出現了:比如下代碼
int main()
{
 std::string strDes("開關_電視臺");
 std::vector<std::string> vecTemp;
 PickUp(strDes,vecTemp,"_");
 system("pause");
 return 0;
}
粗看可能看不出什麼問題,但是結果是錯誤的,仔細斷點跟蹤併網上查閱了相關資料,終於弄懂原因了。
std::string 的find函數是按照單字節查找對比的,而GBK 採用雙字節表示,總體編碼範圍爲 0x8140-FEFE,首字節在 0x81-FE 之間,尾字節在 0x40-FE 之間
而開字的內存數據爲e9 5f,臺字的內存數據爲c5 5f,下劃線"_"的內存爲5f,也就是說開字的尾字節和下劃線ascii"_"是一樣的,不行的是std::string 的find是採用單字節查找的,所以出現的結果是vecTemp的size()變成了4,其中包括兩個空的字符串,而不是預期的結果2;而之前沒有出問題是因爲分隔符分號的緣故";",";"的ascii碼是小於0x40的。
所以解決此種問題的辦法就是分隔符應該去小於0x40也就是ascii碼小於64的,至於哪些小於64就需自己去查了
或者可以自己寫個單字節比較find算法.....

 

boost::tokenizer不錯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章