3

次のJavaコードは、期待どおりの動作をします。

1      String s = "♪♬♪♪♬♪♪♬♪♪♬♪♪♬♪♪♬♪";
2      for(int i=0; i < s.length(); i++)
3      {
4         System.out.print(s.substring(i,i+1));
5         //System.out.print("\r");
6         Thread.currentThread().sleep(500);
7      }

しかし、5行目にコメントしてキャリッジリターンを追加しようとすると、?sが出力されます。なぜそれを修正するにはどうすればよいですか?

(キャリッジリターンには「\ u240d」も試してみました-同じことです)。

編集:出力はMacOSXのbashに送られます。

4

3 に答える 3

4

s.length() も印刷してください。おそらく 18 以上です。Java 文字列表現は utf-16 です。String.substring は char 値を抽出するだけです。音符は 0x1d000 から始まります - それらは単一の文字に収まりません。文字列から完全なコードポイント/グリフを抽出するには、 icu プロジェクトのようなものを使用します - UCharacterIterator

ps: 端末セッションでこれらの文字を表示できるかどうかはわかりません

于 2009-11-20T09:11:42.813 に答える
3

これは、端末が出力をどのように解釈しているかによるものだと思います。

上で指摘したように、すべてのノートグリフはマルチバイト文字です。さらに、Javacharはわずか16ビット幅であるため、char単一のUnicode文字を単独で確実に表すことはできません。その結果、このString.substringメソッドは完全にマルチバイト対応ではありません。

したがって、起こりそうなことは、ループの各反復で、Javaが文字の半分を出力することです。ペアの最初のバイトが出力されると、端末はそれがマルチバイト文字の前半であると認識し、表示しません。次のバイトが出力されると、端末はノートに対応する完全な文字を確認して表示します。

コメントを外すと、各文字の2つの半分の中央にprintln("\r")改行が挿入されます。したがって、端末は、ノートを表す0x26、0x6Cなどのバイトシーケンスを取得することはありませんが、代わりに0x26、0x10、0x6C、0x10を取得するため、ノートはレンダリングされません。

于 2009-11-20T09:26:56.947 に答える
1

Java は、ソース ファイルが UTF-8 であることを認識していません。

でコンパイルすると

javac -encoding utf8 MyClass.java

そして一緒に走る

java -Dfile.encoding=utf8 MyClass

それが動作します。

(UTF-8がデフォルトではない理由を知っている人はいますか?)

于 2009-11-20T10:09:21.307 に答える