3

ギリシャ語の語彙クイズ プログラムを作成しようとしています。問題は、入力文字を正しく解釈できないことです。以下は、問題を示すためにまとめたサンプルコードです。(マシンにギリシャ語の入力を設定する手間をかけたくない場合は、プログラムが単語を要求したときに、ギリシャ語の文字列をコピーして貼り付けることができます。重要な場合は、これを実行しています。 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();
    }
}

出力は次のとおりです。

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

上の単語を入力してください: αβγδεζηθικλμνξοπρσςτυφχψω

これは、コンピューターがキーボードから取得したものです。
αβγδεζηθικλμνξοπÏ�σςτυφχψω
    Î ± Î ² Î ³ Î ´ Î µ Î ¶ Î · Î ¸ Î ¹ Î Î Î » Î ¼ Î ½ Î ¾ Î ¿
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 0x3c5 0x3c8c6


誰でも問題を解決する方法を教えてもらえますか?

4

3 に答える 3

5

コードは、経由で着信するバイトがSystem.inUTF-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がギリシャ文字をバイトに有効にエンコードできるかどうかわからないため、「可能性がある」と言います。)したがって、プログラムが機能するには、2つのことが真実である必要があります。

  1. ラップReaderアラウンド時に使用するエンコーディングは、端末で入力するときにコンピュータがバイトを文字に変換するために使用するのと同じエンコーディングを使用するSystem.in 必要があります。
  2. コンピュータが使用しているエンコーディングが何であれ、ギリシャ文字をそのエンコーディングで有効なバイトシーケンスにエンコードできる必要があります。
于 2012-06-02T00:08:46.100 に答える
0

エンコードの Eclipse 実行/デバッグ構成の「共通」タブを見てください。正しいコード ページまたは ISO コードを入力できます。

于 2012-06-03T02:51:52.713 に答える
0

バグとして報告しましたが、そのように確認されました:

「これは次のリリース (Kepler) で修正されるバグであることを確認しました。」

皆様のご意見をお待ちしております。

于 2012-06-12T16:21:38.247 に答える