java - 如何从键盘读取 Unicode Greek?

标签 java eclipse unicode character-encoding

我正在尝试编写一个希腊语词汇测验程序。问题是我无法正确解释输入的字符。下面是我放在一起演示问题的一些示例代码。 (如果你不想经历为你的机器设置希腊语输入的麻烦,当程序要求输入这个词时,你可以只复制并粘贴希腊语字符串。如果它很重要,我正在运行这个64 位 Win7 上的 Eclipse。)

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class GreekKeyboardExample {

    public static void main(String[] args) {
        String word = "αβγδεζηθικλμνξοπρσςτυφχψω";
        System.out.println("\n\n" + word + "\n");
        String answer = getInput("Type the word above: ");

        System.out.println("\nThis is what the computer took from the keyboard:");  
        printCharsAndCode(answer);

        System.out.println("\nThis is what it should look like:");  
        printCharsAndCode(word);
    }

    private static String getInput(String prompt) {
        System.out.print(prompt);
        System.out.flush();

        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in, "UTF8"));
            return in.readLine();
        } 
        catch (Exception e) {
            return "Error: " + e.getMessage();
        } 
    }

    /* prints the character and its (unicode) code */
    public static void printCharsAndCode(String str) {
//      int len = str.length();
        char[] c = str.toCharArray();
        System.out.println(str);
        for (char d : c) {
            System.out.print("    " + d + " ");
            if (Character.getType(d) == 6) System.out.print(" "); //extra space to make combining diacritics display rightly (NON_SPACING_MARK)
        }
        System.out.println();
        for (char d : c) {
            int ic = (int) d;
            System.out.printf("%1$#05x ", (int) d);
        }
        System.out.println();
    }
}

这是输出:

αβγδεζηθικλμνξοπρσςτυφχψω

Type the word above: αβγδεζηθικλμνξοπρσςτυφχψω

This is what the computer took from the keyboard:
αβγδεζηθικλμνξοπ�σςτυφχψω
    Î     ±     Î     ²     Î     ³     Î     ´     Î     µ     Î     ¶     Î     ·     Î     ¸     Î     ¹     Î     º     Î     »     Î     ¼     Î     ½     Î     ¾     Î     ¿     Ï     €     Ï     �     Ï     ƒ     Ï     ‚     Ï     „     Ï     …     Ï     †     Ï     ‡     Ï     ˆ     Ï     ‰ 
0x0ce 0x0b1 0x0ce 0x0b2 0x0ce 0x0b3 0x0ce 0x0b4 0x0ce 0x0b5 0x0ce 0x0b6 0x0ce 0x0b7 0x0ce 0x0b8 0x0ce 0x0b9 0x0ce 0x0ba 0x0ce 0x0bb 0x0ce 0x0bc 0x0ce 0x0bd 0x0ce 0x0be 0x0ce 0x0bf 0x0cf 0x20ac 0x0cf 0xfffd 0x0cf 0x192 0x0cf 0x201a 0x0cf 0x201e 0x0cf 0x2026 0x0cf 0x2020 0x0cf 0x2021 0x0cf 0x2c6 0x0cf 0x2030 

This is what it should look like:
αβγδεζηθικλμνξοπρσςτυφχψω
    α     β     γ     δ     ε     ζ     η     θ     ι     κ     λ     μ     ν     ξ     ο     π     ρ     σ     ς     τ     υ     φ     χ     ψ     ω 
0x3b1 0x3b2 0x3b3 0x3b4 0x3b5 0x3b6 0x3b7 0x3b8 0x3b9 0x3ba 0x3bb 0x3bc 0x3bd 0x3be 0x3bf 0x3c0 0x3c1 0x3c3 0x3c2 0x3c4 0x3c5 0x3c6 0x3c7 0x3c8 0x3c9 


谁能告诉我如何解决这个问题?

最佳答案

您的代码假定通过 System.in 传入的字节已使用 UTF-8 编码。除非您已将平台的默认编码设置为 UTF-8,否则这种情况不太可能发生。

如果您指定的编码与您平台的默认编码相匹配,而不是 UTF-8,会发生什么情况?

例如,我的 Linux 机器确实将其默认编码设置为 UTF-8,当我运行您的程序时,我得到了“正确”的答案。但是,我确实必须将 word 的定义更改为:

String word = "\u03b1\u03b2\u03b3\u03b4\u03b5\u03b6\u03b7\u03b8\u03b9\u03ba\u03bb\u03bc\u03bd\u03be\u03bf\u03c0\u03c1\u03c3\u03c2\u03c4\u03c5\u03c6\u03c7\u03c8\u03c9";

因为当我尝试将希腊字母剪切并粘贴到我的编辑器中时,我的编辑器不理解它们。将它们作为 unicode 转义序列输入会得到完全相同的字符串,就好像我有一个理解输入其中的希腊字母的编辑器一样。

所以当我运行你的程序时,我得到:

αβγδεζηθικλμνξοπρσςτυφχψω

Type the word above: αβγδεζηθικλμνξοπρσςτυφχψω

This is what the computer took from the keyboard:
αβγδεζηθικλμνξοπρσςτυφχψω
    α     β     γ     δ     ε     ζ     η     θ     ι     κ     λ     μ     ν     ξ     ο     π     ρ     σ     ς     τ     υ     φ     χ     ψ     ω 
0x3b1 0x3b2 0x3b3 0x3b4 0x3b5 0x3b6 0x3b7 0x3b8 0x3b9 0x3ba 0x3bb 0x3bc 0x3bd 0x3be 0x3bf 0x3c0 0x3c1 0x3c3 0x3c2 0x3c4 0x3c5 0x3c6 0x3c7 0x3c8 0x3c9 

This is what it should look like:
αβγδεζηθικλμνξοπρσςτυφχψω
    α     β     γ     δ     ε     ζ     η     θ     ι     κ     λ     μ     ν     ξ     ο     π     ρ     σ     ς     τ     υ     φ     χ     ψ     ω 
0x3b1 0x3b2 0x3b3 0x3b4 0x3b5 0x3b6 0x3b7 0x3b8 0x3b9 0x3ba 0x3bb 0x3bc 0x3bd 0x3be 0x3bf 0x3c0 0x3c1 0x3c3 0x3c2 0x3c4 0x3c5 0x3c6 0x3c7 0x3c8 0x3c9 

它对我有用的原因是我的计算机设置为使用 UTF-8。因此,当我输入终端时,该终端程序和/或操作系统将使用 UTF-8 将这些字符转换为字节,而当 Java 使用 UTF-8 读取这些字节时,一切都很好。

但是如果我的计算机设置为 ISO-8859-1,那么在终端上键入将生成在 UTF-8 中没有意义的字节,并且程序将从键盘读取“垃圾”。但是,如果将程序更改为使用 ISO-8859-1,那么它可能会起作用。 (我说“可能”是因为我不知道 ISO-8859-1 是否可以有效地将希腊字母编码为字节。)。因此,为了使您的程序正常工作,您需要满足以下两点:

  1. Reader 包装在 System.in 中时使用的编码必须使用与计算机将字节转换为字符所使用的编码相同的编码当您在终端输入时。
  2. 无论您的计算机使用何种编码,它都需要能够将希腊字母编码为在该编码中有效的字节序列。

关于java - 如何从键盘读取 Unicode Greek?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10858643/

相关文章:

java - 自定义StdDeserializer不使用指定的@JsonView

python - WxPython 与雪豹不兼容?

Java 构建路径错误 - 无法读取(项目)中的(库)或者不是 Eclipse 中的有效 zip 文件

python - Unicode 和区域设置问题

c++ - 将 unicode 转换为 char

Java - HashMap 内存 : optimization

java - jpa 多对多与附加列

java - 在 Java Eclipse 项目中查找未使用的类

JavaScript:输出符号和特殊字符

java - 在 Java 中将 switch 语句包装在一个整洁的循环中