C++ 确定unicode字符在C+中是全宽还是半宽+;

C++ 确定unicode字符在C+中是全宽还是半宽+;,c++,unicode,C++,Unicode,我正在编写一个终端(控制台)应用程序,它应该包装任意unicode文本 终端通常使用单间距(固定宽度)字体,因此要包装文本,只需计算字符数,观察一个单词是否适合一行,并据此采取行动 问题是Unicode表中有一些全宽字符占用了终端中2个字符的宽度 对这些字符进行计数将看到1个unicode字符,但打印字符的宽度为2个“正常”(半宽度)字符,这打破了包装程序,因为它不知道占用两倍宽度的字符 例如,这是一个全宽字符(U+3004,JIS符号) 〄 12 虽然它是预格式化的,但它在这里不占用2个字符的

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

终端通常使用单间距(固定宽度)字体,因此要包装文本,只需计算字符数,观察一个单词是否适合一行,并据此采取行动

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

对这些字符进行计数将看到1个unicode字符,但打印字符的宽度为2个“正常”(半宽度)字符,这打破了包装程序,因为它不知道占用两倍宽度的字符

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

〄 12 虽然它是预格式化的,但它在这里不占用2个字符的全宽,但它在终端中使用的宽度是西文字符的两倍

为了处理这个问题,我必须区分全宽度或半宽度字符,但是我不能在C++中找到这样的方法。是否真的有必要了解unicode表中的所有全宽字符来解决此问题?

您应该使用ICU和
UCHAR\u EAST\u ASIAN\u 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+0301
组合急性重音只占1个单元格。

无需构建表格,Unicode用户已经完成了以下工作:


相同的代码用于终端仿真软件,如
xterm
konsole
,很可能还有其他相关的…

操作系统/平台?抱歉,我错过了。操作系统是Linux。我不确定终端将如何处理超宽字符。现在不在我的Linux上测试打印௵ 我现在要替换所有给ICU的电话,以尽量减少依赖性。也许我可以借助u_getIntPropertyValue方法构建一个包含所有全宽字符的表。谢谢你对组合角色的提示。我将检查这是否也适用于终端。@不,它可能不再适用于您,但我最近为一个类似的问题整理了字符范围,如下所示:
bool is_fullwidth(UChar32 c) {
    int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
    return width == U_EA_FULLWIDTH || width == U_EA_WIDE;
}