2014-06-18 56 views
2

我不確定我的假設是否正確,但我覺得多字節序列的所有四種長度都可以不同,以說明:以字節爲單位的多字節序列的長度(unicode)代碼點,字符和光標位置

就是說,多字節編碼爲UTF-8,和我們有字符串"\xc3\xb8 \xe2\x86\x82 e\xcc\x88",的"\u00f8 \u2182 e\u0308" 「øↂë」

此字符串的UTF-8編碼的長度爲:

  1. 10字節
  2. 6的unicode碼點
  3. 5個字符
  4. 6屏幕位置(具有寬字體)(ↂ取2個位置)

1)由strlen和2返回)可以被確定與<wchar.h>功能。

但是有沒有一種確定3)和4)的便攜方式? 我不確定,如果ↂ對兩個光標位置定義爲字體無關的代碼點或有關正在使用的字體,我覺得「等寬字體」和「某些字符佔用多個空間」有點矛盾。至少在Monospace這個字符確實包含了兩個光標位置。 Unicode圖表U2150沒有提及光標位置。

最後,對於任何角色(我的意思是一個角色將光標位置左移到左腳本或反之亦然)的位置數量是多少?

回答

2

Posix接口wcwidth可用於查找wchar_t的「光標位置」的數量。爲了獲得wchar_t值(一次一個),可以使用C99標準庫函數mbtowc,該函數從字符串中提取單個多字節字符並返回消耗的字節數。 (反覆呼籲串mbtowc並更新字符串的指針每次都會告訴你有多少多字節字符如何出現在字符串中,至少如果多字節編碼是UTF-8)。

wcwidthmbtowc的組合可以或多或少地告訴你字符串中有多少個字形(你的問題#3)。 wcwidth返回0的wchar_t是零寬度格式控件或組合字符,並且wcwidth返回-1的wchar_t可以是非字符或控制字符(如\n)。無論哪種方式,它都可以被忽略,所以字形計數實際上是寬度大於0的wchar_t的計數。

這清楚地表明,這四個問題有不同的答案:

  1. 的字節數。

  2. 多字節碼點的數量。

  3. 數字節碼點,其wcwidth是多字節碼點,其wcwidth的wcwidth大於0

  4. 總和大於0

說了這麼多,有不能保證wcwidth返回的值對應於當前控制檯字體的實際字符寬度或應用程序正在使用的Unicode版本。 (我遇到了這兩個問題。)wcwidth返回的值是從當前語言環境中提取的,因此您可以編輯和重新編譯您的語言環境文件以修復錯誤。例如,請參閱我的答案:How to get ncurses to output astral plane unicode characters

2

但是有沒有一種確定[字符和光標位置]的便攜方式?

這兩個都是模糊概念。例如,羅馬人10,000是某些字體中的兩個光標位置可能取決於特定應用程序如何選擇呈現它。

一般來說,人們依靠平臺(例如本地文本渲染引擎)或像ICU這樣的庫來獲取諸如光標位置和形狀字形之類的東西。