2

さまざまなマシンでのトルコ語の特殊文字に問題があります。次のコード:

String turkish = "ğüşçĞÜŞÇı";

String test1 = new String(turkish.getBytes());
String test2 = new String(turkish.getBytes("UTF-8"));
String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");

System.out.println(test1);
System.out.println(test2);
System.out.println(test3);

Mac では、3 つの文字列は元の文字列と同じです。Windows マシンでは、3 行は次のようになります (Netbeans 6.7 コンソールで出力):

?ü?ç?Ü?Ç?
ğüşçĞÜŞÇı
?ü?ç?Ü?Ç?

問題がわかりません。

4

4 に答える 4

11
String test1 = new String(turkish.getBytes());

トルコ語の文字を含む Unicode 文字列を取得し、デフォルトのエンコーディングを使用してバイトに変換しています (デフォルトのエンコーディングを使用するのは通常間違いです)。次に、それらのバイトを取得し、再びデフォルトのエンコーディングを使用して文字列にデコードします。その結果、何も達成できませんでした (デフォルトのエンコーディングに収まらない文字を失うことを除いて)。文字列をエンコード/デコードサイクルに通したかどうかは、バイトではなく文字列を出力しているため、次の動作には影響しません。System.out.println(test1)

String test2 = new String(turkish.getBytes("UTF-8"));

UTF-8 としてエンコードしてから、デフォルトのエンコーディングを使用してデコードします。Mac では、デフォルトのエンコーディングは UTF-8 であるため、これは何もしません。Windows では、デフォルトのエンコーディングは決して UTF-8 ではないため、結果は間違った文字になります。

String test3 = new String(turkish.getBytes("UTF-8"), "UTF-8");

正確には何もしません。

デフォルトのエンコーディングとは異なるエンコーディングで文字列を stdout に書き込むには、次のようなエンコーダを作成しnew OutputStreamWriter(System.out, "cp1252")、文字列の内容をそれに送信します。

ただし、この場合、コンソールは Windows コード ページ 1252 西ヨーロッパ (+1 ATorres) を使用しているようです。ここにはエンコードの不一致の問題はまったくないため、文字列を再エンコードしても解決できません!

デフォルトのエンコーディング cp1252 はコンソールのエンコーディングと一致しますが、cp1252 にはトルコ文字がまったく含まれていないだけですğşĞŞı。cp1252 にある他の文字üçÜÇ正常に表示されることがわかります。必要なすべての文字を含む別のエンコーディングを使用するようにコンソールを再構成できない限り、それらの文字を出力する方法はありません。

おそらくトルコ語の Windows インストールでは、デフォルトのコード ページは代わりに cp1254 になり、期待どおりの文字が得られます (ただし、他の文字は機能しません)。これは、[地域と言語のオプション] コントロール パネル アプリで [非 Unicode アプリケーションに使用する言語] 設定を変更することでテストできます。

残念ながら、デフォルトのコード ページとして UTF-8 を使用する Windows ロケールはありません。stdio ストリーム関数を使用して非 ASCII 出力をコンソールに出力することは、まったく信頼できるものではありません。Unicode をコンソールに直接書き込むための Win32 API がありますが、残念ながらそれをあまり使用していません。

于 2009-12-15T15:37:20.870 に答える
6

コンソールやデフォルトのプラットフォーム エンコーディングに依存しないでください。like の呼び出しとバイト配列を取る String コンストラクターの文字エンコーディングを常に指定し、getBytes文字列の内容を調べたい場合は、各文字の Unicode 値を出力します。

また、ソース コードで ASCII (および \uxxxx を使用して非 ASCII 文字をエンコード) を使用するように制限するコンパイル時に文字エンコードを明示的に指定することをお勧めします。

さて、あなたが解決しようとしているより大きな問題は何ですか?

于 2009-12-15T13:18:51.680 に答える
2

デフォルトのエンコーディングのさまざまな設定を扱っている可能性があります。

java -Dfile.encoding=utf-8

java -Dfile.encoding=something else

または、Mac ターミナル ウィンドウが UTF-8 で動作し、Windows DOS ボックスが UTF-8 で動作しないという事実が表示されているだけかもしれません。

Skeet 氏によると、ソースに UTF-8 文字を埋め込もうとしているという 3 つ目の問題が考えられます。コンパイラ オプションによっては、意図したものが得られる場合と得られない場合があります。このデータをプロパティ ファイルに入れるか、\u エスケープを使用します。

最後に、Skeet 氏によると、引数なしの getBytes() は絶対に呼び出さないでください。

于 2009-12-15T13:21:15.137 に答える
0

AspectJ コンパイラを使用している場合は、エンコーディングも UTF-8 に設定することを忘れないでください。これを見つけるのに何時間も苦労しました。

于 2009-12-15T13:28:36.683 に答える