2015-10-04 195 views
-2

可以使用類似於這個的方法來完成:在C中獲取UTF-8上的字符串長度?

只要用戶通過scanf輸入的字符串的當前元素不是\ 0,向「length」int添加一個,然後打印出長度。

如果有人能指導我通過最簡單的方式,因爲我是初學者,我將不勝感激。

非常感謝,有一個很好的!

+0

'mblen()/ mbrlen()'找到每個字符的長度,然後編寫自己的函數迭代字符串直到終止符,添加字符的長度? – EOF

+0

您的方法將返回字節數,就像任何以零結尾的字符串一樣。聽起來就像你想要的字符數量,但是。無論哪種方式,這是一個常見問題,它應該很容易找到滿足您的要求的重複(以及解釋你正在掩飾的複雜情況)。 – tripleee

+0

可能重複的[UTF-8字符串的長度在Linux中,C](http://stackoverflow.com/questions/5117393/utf-8-strings-length-in-linux-c) – tripleee

回答

4

你是什麼意思字符串長度

使用strlen(s)很容易獲得字節數。

通過計算單字節字符數(範圍1至127)和前導字節數(範圍0xC0至0xFF),忽略連續字節(範圍0x80),可以計算以UTF-8編碼的代碼點數到0xBF)並停止在'\0'

下面是一個簡單的函數來做到這一點:

size_t count_utf8_code_points(const char *s) { 
    size_t count = 0; 
    while (*s) { 
     count += (*s++ & 0xC0) != 0x80; 
    } 
    return count; 
} 

該函數假定數組的內容指向s被正確編碼。

另請注意,這將計算代碼點的數量,而不是顯示的字符數,因爲其中一些可能使用多個組合代碼點進行編碼,例如<LATIN CAPITAL LETTER A>,然後是<COMBINING ACUTE ACCENT>

+0

正確,除了你的範圍應該是0xC2到0xF4,否則會有無效的UTF-8序列,因爲沒有超出U + 10FFFF(F4 8F BF BF)的代碼點,並且0xC1和0xC0都會表示[過長的字節序列](https://en.wikipedia .org/wiki/UTF-8#Overlong_encodings),這是無效的。 –

+0

@ChronoKitsune:如上所述,該函數不會嘗試檢查正確的編碼。如果字符串編碼正確,該函數將返回正確數量的代碼點。如果不是,您提議的更改將不能提供完整的字符串驗證:計數連續字節,檢查過長的序列和無效的代碼點將需要更多的代碼。 – chqrlie

+0

我想如果你能夠信任輸入數據,那麼事實是你的代碼是足夠好的,不會因驗證而減慢任何東西。 –