2012-06-01 52 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