3

90 年代前半に書かれた古い Java ゲームのソース コードをいじっています。私の記憶が正しければ、JDK 1.1 用に書かれています。

コードのどこかで、int プリミティブ (0 から約 120 の範囲) が char に変換されます。次に例を示します。

char c = (char)(i+32);

これにより、int が 95 より大きい場合に問題が発生します。コードとテスト ケースからの出力の一部を次に示します。

for(int i = 120; i >= 0; i--)
   System.out.println(i + " -> " + (char)(i+32));

出力:

...
100 -> ?
99 -> ?
98 -> ?
97 -> ?
96 -> ?
95 -> 
94 -> ~
93 -> }
92 -> |
91 -> {
90 -> z
89 -> y
88 -> x
87 -> w
...
3 -> #
2 -> "
1 -> !
0 ->  

インデックスが通常の文字値の境界を超えるため、整数値が失われたようです。

これが、ゲームの UI のクライアント側部分のバグの根本的な原因のようです。このエンコードされた整数はクライアントに送り返され、クライアントは逆の操作を実行します (char から 32 を引き、キャストして int を取得します)。

「?」のようです バーは「?」のマップされた整数値で重複して埋められるため、クライアント側処理モジュールによって文字どおりに解釈されます。サーバーが 95 より小さい値を送り返すまで。

  1. 作成者のプラットフォームで使用された可能性のある文字エンコーディングは?
  2. 私のプラットフォームでは、具体的に何が違うのでしょうか?
  3. この問題の最も簡単な解決策は何だと思いますか?
4

4 に答える 4

2

インデックスが通常の文字値の境界を超えるため、整数値が失われたようです。

まあ、それは実際には「失われた」わけではありません -制御文字の範囲に入るだけです。

作成者のプラットフォームで使用された可能性のある文字エンコーディングは?

これがどのプラットフォームでも「通常の」エンコーディングであるとは思いません。

私のプラットフォームでは、具体的に何が違うのでしょうか?

あなたが何を期待していたのかは明確ではありませんが、これらの文字はコンソールで表示できないため、「?」に変換しています。

この問題の最も簡単な解決策は何だと思いますか?

これに対する解決策を得るには、何をしたいのかという観点から、問題をより適切に定義する必要があります。これが本当にコンソール ゲームなのか、それとも何か別のものなのか、あるいは何をしたいのかは明らかではありません。

最初にどのような振る舞いをしたいのかを正確に考えてください。そうすれば、それを達成するのは非常に簡単かもしれません. . 多くの場合、それを非常に具体的に定義するだけで十分です。

于 2012-05-06T15:01:01.030 に答える
1

この問題の最も簡単な解決策は何だと思いますか?

まず、アプリケーションが実際に何を出力しようとしているのかを理解する必要があります。つまり、これらの整数値が実際に意味するもの。これにより、それらを(おそらく)印刷可能な文字にレンダリングするための要件が​​決まります。

単純に整数を印刷可能なものとしてレンダリングしようとしている場合は、文字の配列として実装されたルックアップ テーブルを使用して実行できます。例えば

char[] map = new char[128];  // ... or whatever the limit is 
for (int i = 0; i < 96; i++) {
    map[i] = (char) (i + 32);
}
// fill the rest of the array with suitable Unicode characters.
map[96] = ...
map[97] = ...

次に、次のように文字をマッピングします。

char c = (i >= 0 && i < 128) ? map[i] : '?'; // ... or throw an exception.
于 2012-05-06T15:16:45.790 に答える
1

charin Java は 16 ビット Unicode 文字です。古いコードは int 値をバイトとして扱うことを期待していた可能性があり、その後、意味のあるもの (つまりnew String(byteArrayData, "ASCII")) が得られるまで、異なる文字セットを指定してバイトを char に変換できます。

考慮する必要があるのは、バイトが Java で署名されているため、-128->+127 の範囲であるということです。古いゲーム コードが拡張 ascii セット (> 127) の値を使用することを想定していた場合、正しいバイト値を取得するには、127 より大きい int から 256 を引く必要があります。参照: Java はどのように int をバイトに変換しますか? 詳細については。

于 2012-05-06T15:21:56.107 に答える
0

80 ~ 9F の範囲の文字が表示される Win1252 などの 8 ビット エンコーディングが使用された可能性があります。

http://en.wikipedia.org/wiki/Windows-1252を参照してください。

于 2012-05-06T15:24:34.490 に答える