【问题标题】:Print chess symbols using UnicodeBlock?使用 UnicodeBlock 打印国际象棋符号?
【发布时间】:2019-10-01 12:17:23
【问题描述】:

有了jdk12,出现了国际象棋符号(source):

Unicode 11.0.0 引入了以下现在包含在 JDK 12 中的新功能

[...] 4 个块用于以下现有脚本:

  • 格鲁吉亚语扩展

  • 玛雅数字

  • ndic Siyaq 号码

  • 国际象棋符号

考虑到这一点,我尝试使用以下代码打印这些字符,以测试功能并在以后的小象棋游戏中使用它们:

Character.UnicodeBlock block = Character.UnicodeBlock.CHESS_SYMBOLS;
for (int i = 0; i < 1114112; i++) {
    char unicode = (char) i;
    if(Character.UnicodeBlock.of(unicode) == block) {
        System.out.println(unicode);
    }
}

但是,它没有打印任何东西。如果我将CHESS_SYMBOLS 替换为例如ARABIC,则该代码有效。我有 java 12.0.1。

问题:为什么上面的代码没有打印任何东西?

【问题讨论】:

  • @StephenC 我正在使用 Intellij,如果我尝试 System.out.println("♔"); 它会打印符号,所以我相信它与代码严格相关
  • @SteveSmith 它没有打印矩形,它根本没有打印任何东西。另外我想使用UniblockCode 进行打印,或者至少了解它为什么不起作用。
  • 您只检查前 65536 个字符,有 1,114,112 个 Unicode 字符。
  • @JGNI 我编辑了代码,但仍然没有打印。我也试过Character.MAX_VALUE

标签: java unicode java-12


【解决方案1】:

Miscellaneous Symbols 块中存在一些国际象棋符号字符,但您专门检查不同块中的 16 位 char 值。 Chess Symbols 块包含具有 16 位值的 个字符;它从 U+1FA00 开始,到 U+1FA6F 结束。

通过转换为char,您将所有高于 U+FFFF 的值修剪为它们的最低 16 位;例如,如果 i0x1fa60,将其转换为 char 将使其成为 0xfa60,这会阻止您的块检查成功。

要使您的代码正常工作,您需要停止假设所有代码点都是 16 位值。你可以通过改变这个来做到这一点:

char unicode = (char) i;

到这里:

int unicode = i;

【讨论】:

  • 当然,将char unicode = (char) i; 更改为int unicode = i; 时,根本不需要两个不同的变量。
【解决方案2】:

不幸的是Character.UnicodeBlock 没有方法来判断块内代码点的开始值和结束值是什么。在 Unicode 11 中,国际象棋符号块从 U+1FA00 运行到 U+1FA6D。

Java 使用 UTF-16 和 surrogate pairs to represent characters over U+10000。在这种情况下,代码点 U+1FA00 将表示为两个 char 值:U+D83E(高代理)和 U+DE60(低代理)。

您应该使用Character.toChars() 正确打印始终为int 的代码点:

Character.UnicodeBlock block = Character.UnicodeBlock.CHESS_SYMBOLS;
for (int i = 0; i < 1114112; i++) {
    if (Character.UnicodeBlock.of(i).equals(block)) {
        System.out.println(Character.toChars(i));
    }
}

【讨论】:

    猜你喜欢
    • 2012-03-25
    • 1970-01-01
    • 2015-05-02
    • 2022-06-17
    • 1970-01-01
    • 2021-12-15
    • 2014-03-02
    • 1970-01-01
    • 2013-05-24
    相关资源
    最近更新 更多