【问题标题】:How to read Unicode Greek from the keyboard?如何从键盘读取 Unicode Greek?
【发布时间】:2012-06-01 23:47:48
【问题描述】:

我正在尝试编写一个希腊语词汇测验程序。问题是我无法正确解释输入字符。下面是我整理的一些示例代码来演示该问题。 (如果您不想为您的机器设置希腊语输入的麻烦,当程序要求输入单词时,您可以复制并粘贴希腊语字符串。如果它很重要,我正在运行它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();
    }
}

这是输出:

αβγδεζηθικλμνξοπρσςτυφχψω 输入上面的单词:αβγδεζηθικλμνξοπρσςτυφχψω 这是计算机从键盘获取的内容: αβγδεζηθικλμνξοπÏ�σÏ,τυφχψω Î ± Î ² Î ³ Î ´ Î µ Î ¶ Î · Î ¸ Î ¹ Î º Î » Î ¼ Î ½ Î ¾ Î ¿ Ï € Ï � Ï ƒ Ï ‚ Ï „ Ï … Ï † Ï ‡ Ï Ï ‰ 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 这应该是这样的: αβγδεζηθικλμνξοπρσςτυφχψω α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ σ ς τ υ φ χ ψ ω 0x3b1 0x3b2 0x3b3 0x3b4 0x3b5 0x3b6 0x3b7 0x3b8 0x3b9 0x3ba 0x3bb 0x3bc 0x3bd 0x3be 0x3bf 0x3c0 0x3c1 0x3c3 0x3c2 0x3c4 0x3c79033x

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

【问题讨论】:

    标签: java eclipse unicode character-encoding


    【解决方案1】:

    您的代码假定通过 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 转义序列输入会得到 exactly 相同的字符串,就好像我有一个可以理解输入希腊字母的编辑器一样。

    因此,当我使用该更改运行您的程序时,我得到:

    αβγδεζηθικλμνξοπρσςτυφχψω
    
    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. 无论您的计算机使用什么编码,它都需要能够将希腊字母编码为在该编码中有效的字节序列。

    【讨论】:

    • +1 用于解释两端的重要性:提供者 - 控制台,阅读器 - 应用于 System.in 的编码。
    • 感谢您的回复,QM。不幸的是 ISO-8859-1 不编码希腊语。所以我需要找到一些方法来弄清楚如何将我的 Win7 机器设置为 UTF8。 (我已经将 Eclipse 设置为 UTF8,因为听起来您需要对编辑器执行此操作。)
    • 我确实找到了这个:Setting UTF8 as default Character Encoding in Windows 7? 我已经做出了它对 Eclipse 建议的更改——没有帮助。唉,它说没有办法为整个操作系统设置编码。所以这让我回到了以前的位置。您还能提供其他指导吗?
    • 除非您将系统默认 ('ANSI') 代码页设置为希腊语(代码页 1253),否则您无法获得使用 C 标准 I/O 库(包括 Java)的控制台程序读希腊文。对不起。 Windows 命令提示符只能将 Unicode 与编译为使用 Windows 特定 Unicode 接口的程序对话,而 MSVCRT 应用程序则不能。缺乏对 UTF-8 的支持是 Windows 下控制台应用程序长期存在的痛点。
    • 感谢您的回复,QuantumMechanic 和 bobince——他们很有启发性! Bobince,Win 命令提示符的问题很有趣,但我真的在询问 Eclipse 控制台。我查看了here 并设置了 UTF-8,但没有任何乐趣。
    【解决方案2】:

    查看 Eclipse 运行/调试配置的“通用”选项卡以了解编码。您可以输入正确的代码页或 ISO 代码。

    【讨论】:

    • 感谢您的回复。在昨天发表评论之前我没有看到它(“感谢您的回复,QuantumMechanic 和 bobince...”),但我已经尝试过了。关于这是否是我应该报告的错误的任何意见?
    • 作为记录,我已通过 Run Configurations > Common > Encoding 将编码设置为 UTF-8,但也通过 Window > Preferences > General > Content类型.
    【解决方案3】:

    我将它报告为a bug,而它只是confirmed

    “我确认这是一个错误,将在下一个版本 (Kepler) 中修复。”

    感谢大家在这里的意见。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-04
      相关资源
      最近更新 更多