2009-09-30 82 views
11

我知道有關於utf-8的各種問題,主要是關於圖書館來處理像對象一樣的utf-8'字符串'。我正在研究一個'國際化'的項目(一個網站,我編寫了一個C++後端...不問),即使我們處理utf-8,我們也不需要這樣做庫。大多數情況下,普通的std :: string方法或STL算法都足以滿足我們的需求,實際上這是首先使用utf-8的目標。在c + +的Utf-8:快速和骯髒的技巧

所以,我在找在這裏是你知道的相關UTF-8存儲的std :: string(沒有爲const char *的「快速&髒」技巧的資本,我不關心c風格的代碼真的,我有更好的事情要做,而不是經常擔心我的緩衝區大小)。

例如,這裏是一個「快速&髒」伎倆獲得的字符數(這是很有必要知道它是否適合你的顯示框):

#include <string> 
#include <algorithm> 

// Let's remember than in utf-8 encoding, a character may be 
// 1 byte: '0.......' 
// 2 bytes: '110.....' '10......' 
// 3 bytes: '1110....' '10......' '10......' 
// 4 bytes: '11110...' '10......' '10......' '10......' 
// Therefore '10......' is not the beginning of a character ;) 

const unsigned char mask = 0xC0; 
const unsigned char notUtf8Begin = 0x80; 

struct Utf8Begin 
{ 
    bool operator(char c) const { return (c & mask) != notUtf8Begin; } 
}; 

// Let's count 
size_t countUtf8Characters(const std::string& s) 
{ 
    return std::count_if(s.begin(), s.end(), Utf8Begin()); 
} 

其實我還沒有遇到一個用例時,我需要什麼比字符數和的std :: string或STL算法否則不提供免費的,因爲:

  • 排序按預期工作
  • 沒有一個字的一部分可以被混淆,一個字一個字或部分

我想知道你是否有其他類似的技巧,既爲計數和其他簡單任務。
我再說一遍,我知道ICUUtf8-CPP,但我對它們不感興趣,因爲我不需要一個完整的治療(實際上我從來不需要超過字符數)。
我也重複說我對char *的處理不感興趣,它們是老式的。

+9

那麼結合變音符號對你無關緊要?這很傷心。他們可能是你算的人物,但他們不佔用更多的空間。實際上任何組合角色。或零寬度的空間。排序如預期般運作?你能指望什麼?如果有意不使用Unicode(除非是某種字節數組),那麼任何特定於語言環境的排序如何知道排序規則。 – Joey 2009-09-30 18:02:02

+0

查看我的編輯,我的應用程序是網站的後端,因此語言環境在瀏覽器中。我們從來沒有遇到過結合角色的問題,我聽說過他們,但從未見過他們,你遇到過哪些語言? – 2009-09-30 18:14:45

+0

幾個不適用於非英文文本的用例:排序,案例摺疊,匹配(例如德語ß和ss)。 – 2009-09-30 18:26:12

回答

5

那麼這個骯髒的把戲將無法正常工作。 一,什麼是面膜的值之後這樣的:

const unsigned char mask = 0x11000000; 
    const unsigned char notUtf8Begin = 0x10000000; 

二進制也許你混合十六進制表示。

其次,正如你在utf-8編碼中所說的,一個字符可能有幾個字節長。 std :: count_if將遍歷UTF8序列中的所有字節。 但實際需要的是查看每個字符的前導字節,並跳過其餘字符直到下一個字符到來。

要使用簡單掩碼錶作爲前導字節,執行計算並向前跳轉 並不困難。

最後你會得到相同的O(n)來檢查字符,並且它將與每個UTF8字符串一起工作。

+0

是的,把我的面具弄混了,對不起。但是,除了組合變音符號問題之外,count_if仍然正確。 – 2009-10-02 12:23:56

+0

我正在研究一個utf8字符串類,其中++會正確地遍歷寬代碼點,並放棄從字節跳轉到字節的偏移量數組。它向前發展很好,但因爲它沒有提供任何好處。迂迴代碼更容易維護。 – jmucchiello 2009-10-08 19:34:17

1

將UTF_8排序爲二進制不會按'Unicode'順序排序。 BOCU-1會。正如所說,你的「如預期」對非英語內容來說是一個相當低的標準。

0

我們在OpenLieroX(我認爲這真的很好)中也是這樣處理的。

對於這樣的UTF-8 std :: strings我們有一堆有用的函數/算法。見Unicode.hUnicode.cpp。例如,有UTF8迭代器,一些簡單的操作操作符(插入或擦除),大小寫轉換,獨立於案例的搜索等。

但是,不要指望這些函數總是正確的。例如,他們不知道如何組合符號或可能的不同方式來編碼相同的文本。

相關問題