【发布时间】:2013-10-03 05:23:15
【问题描述】:
我们在将以下逻辑从 C++ 移植到 Java 时遇到问题。 Java 方法应该返回与 C++ 函数相同的值。如果 keyValue 包含非 ASCII 字符,则逻辑失败。
C++函数如下,
int CMyClass::KeyToId( const char *keyValue ) {
int sum = 0, len = strlen( keyValue );
// Get a sum based on the characters in the string.
// Each character contributes + <ASCII-value> * 11.
for( int i = 0; i < len; i++ ) sum += keyValue[i] * 11;
// Modulo the result to get a value in the standard range.
return sum;
}
在第 2 行,keyValue[i] 被转换为 8 字节的 ascii 码。
Java 的确切端口如下所示:
private int keyToId(String keyValue) {
int sum = 0, len = keyValue.length();
// Get a sum based on the characters in the string.
// Each character contributes + <ASCII-value> * 11.
for( int i = 0; i < len; i++ )
sum += keyValue.charAt(i) * 11;
return sum;
}
在 Java 中,字符 keyValue.charAt(i) 被转换为“unicode”值。我想不出一种简单的方法将其转换为等效的 ASCII 码。 C++ 应用程序是非 unicode 应用程序。请假设,我们无法更改 C++ 逻辑。
更多输入: 我正在用俄语运行应用程序。对于 красный 的输入,C++ 应用程序返回 -1452。我想从 Java 代码中获得相同的值。
【问题讨论】:
-
如果您在 Windows 上运行,代码页为 1251,字符串 красный 应编码为 [-22, -16, -32, -15, -19, -5, -23] 和您显示的 C++ 代码应计算 -1452。您可以手动验证。如果它真的返回 -300,那么代码必须做的事情比你所展示的要多。
-
结果取决于编码,UTF-8 会给出另一个结果。主要问题是 ASCII(一个美国标准)涵盖俄语的错误假设。
-
@Joni -1452 是正确的结果。分享前排除了部分代码,忘记重新计算结果。
-
"在 Java 中,字符 keyValue.charAt(i) 被转换为 "unicode" 值。"不,它返回 UTF-16 代码单元值,仅当 Unicode 代码点在 [U+0000, U+FFFF] 范围内时,它才会与 Unicode 代码点值相同。如果 UTF-16 代码单元值在 [U+D800, U+DCFF] 范围内,那么您有一个代理代码点,实际 Unicode 代码点值在 [U+10000, U+10FFFF] 范围内并且不适合 Java 2 字节
char。
标签: java c++ unicode localization ascii