如何从键盘读取Unicode希腊语?

Joh*_*hnK 3 java eclipse unicode character-encoding

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

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是输出:

?????????????????????????

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 


任何人都可以告诉我如何解决这个问题?

Qua*_*nic 5

您的代码假定来自via的字节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";
Run Code Online (Sandbox Code Playgroud)

因为当我尝试将希腊字母剪切并粘贴到我的编辑器中时,我的编辑不理解它们.将它们作为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 
Run Code Online (Sandbox Code Playgroud)

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

但是如果我的计算机设置为ISO-8859-1,那么在终端输入会生成UTF-8无效的字节,并且程序会从键盘读取"垃圾".但是如果程序改为使用ISO-8859-1,那么它可能会有效.(我说"可能",因为我不知道ISO-8859-1是否可以有效地将希腊字母编码为字节.).因此,要使您的程序正常工作,您需要做两件事:

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

  • 除非您将系统默认('ANSI')代码页设置为希腊语(代码页1253),否则无法获得使用C标准I/O库(包括Java)的控制台程序来读取希腊语.抱歉.Windows命令提示符只能将Unicode与编译为使用特定于Windows的Unicode接口的程序进行通信,而MSVCRT应用程序则不能.缺乏对UTF-8的支持是Windows下控制台应用程序长期存在的痛点. (2认同)