2009-11-24 62 views
0

我正在處理一些處理字符串的小型C++應用程序。目前,我想要在特定字符索引處提取字符串。我的使用字符串的at()方法的天真解決方案工作正常,但它打破了非ASCII字符串。例如:C++中的非ASCII字符串字符索引

string test = "ヘ(^_^ヘ)(ノ^_^)ノ" 
cout << test.at(0) << endl; 

在gcc 4.2下生成一個英鎊符號作爲輸出。我認爲我的終端也不是問題,因爲我可以打印出整個字符串。有沒有圖書館或我可以用來獲得所需效果的東西?

回答

2

string使用char這僅僅是8位。如果要編碼16位字符,則需要使用wstring

+0

和'的std :: wcout' – GManNickG 2009-11-24 01:29:03

1

你的字符串可能是UTF-8,其中「字符」和「字節」不是一回事。 std::string類假設「字符」每個都是一個字節,所以結果是錯誤的。

你的選擇是對的字符串轉換爲UTF-16轉換和使用wstring相反,在那裏你可以(一般)假設的人物都是兩個字節(一wchar_tshort)每次,或者你可以像使用ICU庫或UTF8-CPP直接對UTF-8字符串進行操作,像「獲取第三個字符」而不是「獲取第三個字節」。或者,如果你想走極簡主義,你可以編寫一個(相對)簡單的函數,通過重用一個UTF-8字符串長度函數的內部來得到特定字符的字節偏移量和長度來自上面列出的一個庫或谷歌。基本上你必須檢查每個字符並向前跳1-3字節,以根據設置的位設置下一個字符的開始。

下面是一個可以從PHP很容易地轉換:

for($i = 0; $i < strlen($str); $i++) { 
    $value = ord($str[$i]); 
    if($value > 127) { 
     if($value >= 192 && $value <= 223) 
      $i++; 
     elseif($value >= 224 && $value <= 239) 
      $i = $i + 2; 
     elseif($value >= 240 && $value <= 247) 
      $i = $i + 3; 
     else 
      die('Not a UTF-8 compatible string'); 
     } 
    $count++; 
} 

http://www.php.net/manual/en/function.strlen.php#25715