私はJavaを使い慣れていません。私はUnicodeに関連していると思ういくつかの問題があります。Java Unicodeの問題(私だと思います)
私はScanner
を使用して、UTF-8エンコーディングで保存されたテキストファイルからトークン化されたコマンドを読み込みました。基本的には、コマンドが "command1"または "command2"(これらの場合は何か他のことをしている)と等しくないことを最初に確認し、それ以外の場合は文字を読み込みます。トークンが1文字でない場合は、エラーを出力します。ここで
は私のコードです:
public static void main(String[] args) throws FileNotFoundException {
Scanner scanner = new Scanner(new File(args[0]));
while (scanner.hasNext()) {
String command = scanner.next();
if (command.equals("command1")) {
System.out.println("command: command1");
// do something
} else if (command.equals("command2")) {
System.out.println("command: command2");
// do something
} else {
if (command.length() == 1) {
char c = command.charAt(0);
System.out.println("character: " + c);
// do something with c
} else {
System.err.println("error (string was " + command
+ " with length " + command.length() + ")");
}
}
}
}
とファイル名、私はテストのために[0]引数に渡しているテキストファイルの内容:
command1
x
y
command2
z
└
command1
╒
═
期待出力は次のとおりです。
command: command1
character: x
character: y
command: command2
character: z
character: └
command: command1
character: ╒
character: ═
実際の出力は:
です。command: command1
character: x
character: y
command: command2
character: z
error (string was └ with length 3)
command: command1
error (string was ╒ with length 3)
error (string was ═ with length 3)
ご覧のとおり、非標準文字はJavaによって3文字の文字列として認識されています。不思議なことに、端末出力の文字の1つをSystem.out.println("└".length())
ステートメントにコピー/ペーストすると、正しく1
が印刷されます。
どこが間違っているのでしょうか?
ありがとう
"トークンが1文字でない場合は、エラーを出力します。" 'String'の' length() 'メソッドは、文字数ではなく、UTF-16コード単位の数を返します。これらはしばしば同じではありません。 – bames53
@ bames53それを指摘してくれてありがとう。 Stringが単一の文字であるかどうかをテストする良い方法がありますか、これはちょっとしたことに気を付けるだけの可能性がありますか? – chigley
「シングルキャラクター」の意味によって異なります。コード・ポイントが文字であるというユース・ケースの合理的な定義であれば、サロゲート・ペアを監視する必要があります。文字を組み合わせるようなことを可能にする定義が必要な場合は、おそらくUnicodeのプロパティやその他のものについてすべて知っているライブラリが必要になるでしょう。 - Unicodeテキストの扱いは複雑です。正直なところ、そこにあるソフトウェアの多くは間違っているが、それでも有用である。だからあなたはそれについて少し勉強したいかもしれませんが、実装する努力の価値がないと決めるかもしれません。 – bames53