如何計算unicode字符在C++中的UTF-8文件中?也許如果有人會如此友善地向我展示「獨立」方法,或者使用http://icu-project.org/index.html作爲簡單示例。在C++中統計unicode字符
編輯:一個重要的條件是,我需要建立每個字符的計數,所以它不喜歡我數字符的總數,而是一組字符的出現次數。
如何計算unicode字符在C++中的UTF-8文件中?也許如果有人會如此友善地向我展示「獨立」方法,或者使用http://icu-project.org/index.html作爲簡單示例。在C++中統計unicode字符
編輯:一個重要的條件是,我需要建立每個字符的計數,所以它不喜歡我數字符的總數,而是一組字符的出現次數。
在UTF-8,非前導字節總是設置爲10
頂部的兩個位,所以只是忽略所有這樣的字節。如果你不介意額外的複雜性,你可以做更多的事情(根據前導字節的位模式跳過非領先字節),但實際上,除了短字符串之外不太可能發生什麼變化(因爲無論如何,你通常會接近內存帶寬)。
編輯:我最初錯誤地閱讀你的問題,只是詢問如何計算以UTF-8編碼的字符串的長度。如果你想計算字符頻率,你可能想要convert those to UTF-32/UCS-4,那麼你需要一些稀疏陣列來計算頻率。
這很難處理計數代碼點與字符。例如,考慮字符「À」 - 「帶有墳墓的拉丁大寫字母A」。至少有兩種不同的方式來產生這個角色。您可以使用代碼點U + 00C0,它在單個代碼點或中編碼整個事物,您可以使用代碼點U + 0041(拉丁文大寫字母A),然後使用代碼點U + 0300(合併嚴重重音)。
規範化(關於Unicode)意味着將所有這些字符轉換爲相同的形式。您可以將它們全部組合成單個代碼點,也可以將它們全部分成單獨的代碼點。出於您的目的,只要可能,將它們組合成單個代碼點可能更容易。自己寫這個可能不太實際 - 我會使用ICU項目中的normalizer API。
對於Unicode統一化。這也是一個win32 api。 – 2010-08-28 19:29:17
與用C++編寫一個完整的例程的討論是在http://www.daemonology.net/blog/2008-06-05-faster-utf8-strlen.html
如果您知道UTF-8序列格式正確,則很容易。對從零位或兩位開始的每個字節進行計數。第一個條件將討論由單個字節表示的每個代碼點,第二個條件將捕獲每個多字節序列的第一個字節。
while (*p != 0)
{
if ((*p & 0x80) == 0 || (*p & 0xc0) == 0xc0)
++count;
++p;
}
或可替代的批示說,你可以簡單地跳過每一個字節,這是一個延續:
while (*p != 0)
{
if ((*p & 0xc0) != 0x80)
++count;
++p;
}
或者,如果你想成爲超級聰明,使之成爲一條雙內膽:
for (p; *p != 0; ++p)
count += ((*p & 0xc0) != 0x80);
Wikipedia page for UTF-8清楚地顯示了模式。
我不認爲這是一個以語言爲中心的問題。 UTF-8格式非常簡單;從文件解碼應該只有幾行任何語言的代碼。
open file
until eof
if file.readchar & 0xC0 != 0x80
increment count
close file
(file.readchar&0xC0)!= 0x80。至少在C中,!=具有比& – jean 2016-02-26 03:24:53
我知道,這是遲到了這個線程,但它可以幫助
與ICU的東西,我沒有這樣說:
string TheString = "blabla" ;
UnicodeString uStr = UnicodeString::fromUTF8(theString.c_str()) ;
cout << "length = " << uStr.length() << endl ;
你想算的字符或代碼點?根據你的編輯,這聽起來像你會關心正常化。所有答案(截至撰寫本文時)都是關於計數碼點的。 – 2010-08-27 18:16:25
@Logan:「正常化」是什麼意思? – 2010-08-27 18:18:25
Logan是對的。鏈接:http://unicode.org/reports/tr15/ – 2010-08-27 18:35:17