2012-06-01 53 views
3

我想写一个希腊语词汇测验程序。问题是我无法正确解释输入字符。以下是一些示例代码,我将它们放在一起来展示问题。 (如果你不想经历为你的机器设置希腊文输入的麻烦,当程序要求输入这个单词时,你可以复制并粘贴希腊字符串。如果它很重要,我可以通过日食在64位的Win7)如何从键盘上读取Unicode希腊字母?

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 


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

回答

0

我报告说,它为a bug,并一直只是confirmed这样:“我可以证实,这是将被固定在下一版本(开普勒)的错误”

我很欣赏大家在这里的意见。

5

您的代码假定通过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. 无论您的计算机使用何种编码,它都需要能够将希腊字母编码为在该编码中有效的字节序列。
+0

+1用于解释两端的重要性:提供者 - 控制台和读者 - 适用于System.in的编码。 – nhahtdh

+0

感谢您的回复,QM。不幸的是[ISO-8859-1](http://en.wikipedia.org/wiki/ISO/IEC_8859-1)不编码希腊文。所以我需要找到一些方法来弄清楚如何将我的Win7机器设置为UTF8。 (我已经将Eclipse设置为UTF8,因为听起来你需要对你的编辑器做这件事。) – JohnK

+0

我确实发现:[在Windows 7中将UTF8设置为默认字符编码?](http://superuser.com/questions/239810/setting-utf8-as-default-character-encoding-in-windows-7)我已经对Eclipse提出了修改 - 不需要帮助。唉它说,没有办法 设置整个操作系统的编码。 让我回到以前的地方。你可以提供的其他任何指导? – JohnK

0

查看编码的Eclipse Run/Debug配置的'Common'选项卡。您可以输入正确的代码页或ISO代码。

+0

感谢您的回复。在昨天发布评论(“感谢您的回复,QuantumMechanic和bobince ...”)之前,我没有看到它,但我已经尝试过了。任何意见,这是否可能是我应该报告的错误? – JohnK

+0

为了记录,我已将编码设置为UTF-8至 **运行配置>常用>编码**,但也通过 **窗口>首选项>常规>内容类型**。 – JohnK