7

我正在编写一个应该包装任意 unicode 文本的终端(控制台)应用程序。

终端通常使用等宽(固定宽度)字体,因此要换行文本,只需计算字符数并观察单词是否适合一行并采取相应措施。

问题是 Unicode 表中有全角字符占用了终端中 2 个字符的宽度。

计算这些会看到 1 个 unicode 字符,但打印的字符是 2 个“正常”(半角)字符宽,因为它不知道占用两倍宽度的字符,所以会破坏包装例程。

例如,这是一个全角字符(U+3004,JIS 符号)

〄
12

尽管它是预先格式化的,但它在这里并不占用 2 个字符的全部宽度,但它确实使用了终端中西方字符宽度的两倍。

为了解决这个问题,我必须区分全角或半角字符,但我在 C++ 中找不到这样做的方法。真的有必要知道 unicode 表中的所有全角字符来解决这个问题吗?

4

2 回答 2

6

您应该将 ICUu_getIntPropertyValue与该UCHAR_EAST_ASIAN_WIDTH物业一起使用。

例如:

bool is_fullwidth(UChar32 c) {
    int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
    return width == U_EA_FULLWIDTH || width == U_EA_WIDE;
}

请注意,如果您的图形库支持组合字符,那么您在确定序列使用多少个单元格时也必须考虑这些;例如,e后跟U+0301COMBINING ACUTE ACCENT 只会占用 1 个单元格。

于 2013-02-27T14:24:48.443 回答
4

没有必要建立表格,来自 Unicode 的人已经这样做了:

http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c

相同的代码用于终端仿真软件,例如xterm[1]konsole[2]以及很可能的其他软件......

于 2014-07-09T06:00:08.117 回答