我正在搞乱九十年代早期写的旧Java游戏的源代码。如果我没记错的话,那就是为JDK 1.1编写的。
在代码中的某处,int基元(在0到大约120的范围内)被转换为字符。这是一个例子:
char c = (char)(i+32);
这会导致整数大于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 ->
由于索引超过了正常字符值的范围,因此整数值似乎丢失了。
这似乎是游戏用户界面客户端部分错误的根本原因。这个编码的整数被发送回客户端,然后客户端执行逆操作(从char中减去32并转换为返回int)。
似乎'?'从客户端处理模块的字面上看,因为条形图被冗余地填充了映射的整数值,用于'?'直到服务器开始发回小于95的值。
答案 0 :(得分:2)
由于索引超过了正常字符值的范围,因此整数值似乎丢失了。
嗯,它并没有真正“丢失” - 它只是进入range of control characters。
作者平台上可能使用了哪些字符编码?
我不认为这是任何平台上的“正常”编码。
我的平台上究竟发生了什么?
目前还不清楚期望会发生什么,但这些字符无法通过您的控制台显示,因此它会将其翻译为“?”
在您看来,什么是解决此问题的最简单方法?
您必须根据您希望发生的事情来更好地定义问题,以获得解决方案。目前尚不清楚这是真的是控制台游戏还是其他什么,或者你想要发生什么。
确切地确定你想要的行为首先是行为,然后它可能很容易实现它 - 我怀疑问题可能是你没有(还)有一个对最终结果应该是什么的非常明确的想法。通常情况下,只是明确定义这一点的行为足以让你前进。
答案 1 :(得分:1)
在您看来,什么是解决此问题的最简单方法?
首先,您必须了解应用程序实际上尝试输出的内容;即这些整数值的真正含义。这将决定将它们呈现给(我猜)可打印字符的要求。
如果您只是尝试将整数渲染为可打印的东西,那么您可以使用作为字符数组实现的查找表来执行此操作; e.g。
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.
答案 2 :(得分:1)
char
是一个16位的Unicode字符。旧代码可能希望将int值视为字节,然后您可以将字节转换为指定不同字符集的字符,直到您得到一个有意义的字符集(即new String(byteArrayData, "ASCII")
)。
您需要考虑的是字节是用Java签名的,因此范围是-128-> +127。如果您的旧游戏代码期望使用扩展的ascii集(&gt; 127)中的值,那么您需要从任何int&gt;中减去256。 127获取正确的字节值。有关详细信息,请参阅:How does Java convert int into byte?。
答案 3 :(得分:0)
可能是使用了Win752之类的8位编码,它在80-9F范围内有可见字符。