将字符 [2] 转换为无符号短字符时出错

Error converting char[2] to unsigned short?

本文关键字:字符 无符号 出错 转换      更新时间:2023-10-16

编辑:

阅读评论后,多亏了 @M.M 和 @AnttiHaapala,我修复了我的代码,但仍然得到不正确的输出......

新代码:

#include <iostream>
int main() {
    char * myChar;
    myChar = new char[2];
    myChar[1] = 0x00;
    myChar[0] = 0xE0;
    unsigned short myShort;
    myShort = ((myChar[1] << 8) | (myChar[0]));
    std::cout << myShort << std::endl;
    return 0;
}

输出:

65504

或者如果您颠倒顺序

57344

旧帖子:

所以我有一个两字节的值,我正在从文件中读取,并希望转换为无符号的短值,以便我可以使用数值。

示例代码:

#include <iostream>
int main() {
    char myChar[2];
    myChar[1] = 'à';
    myChar[0] = '';
    unsigned short myShort;
    myShort = ((myChar[1] << 8) | (myChar[0]));
    std::cout << myShort << std::endl;
    return 0;
}

输出:

40960

但是àE0 00应该将值 224 作为无符号的双字节值?

也很有趣...

此代码:

include <iostream>
int main() {
    char * myChar;
    myChar = "à";
    unsigned short myShort;
    myShort = ((myChar[1] << 8) | (myChar[0]));
    std::cout << myShort << std::endl;
    return 0;
}

输出:

49920

注意:原始代码有一个复杂的因素,因为源是 UTF-8 编码的。 请查看此答案的编辑历史记录以查看我对此的评论。但是,我认为这不是您要询问的主要问题,因此我更改了答案以仅解决编辑问题。 为避免 UTF-8 转换问题,请使用 'xE0' 而不是 'à'


关于编辑的代码:

char * myChar;
myChar = new char[2];
myChar[1] = 0x00;
myChar[0] = 0xE0;
unsigned short myShort;
myShort = ((myChar[1] << 8) | (myChar[0]));
std::cout << myShort << std::endl;

char范围(在您的系统上(从-128127 。 这很常见。 你写myChar[0] = 224;. (0xE0 是值为 224int文字(。

这是超出范围的转换,会导致实现定义的行为。 最常见的是,实现将定义它以调整模 256,直到值在范围内。因此,您最终得到的结果与以下内容相同:

myChar[0] = -32;

那么计算(myChar[1] << 8) | myChar[0]0 | (-32),即-32。 最后,您转换为 unsigned short . 这是另一个超出范围的转换,因为unsigned short的范围在您的系统上[0, 65535]

但是,在这种情况下,明确定义了到无符号类型的范围转换以调整模65536,因此结果为 65536 - 32 = 65504


反转顺序执行((-32) << 8) | 0 。 左移负值会导致未定义的行为,尽管在您的系统上它已表现为执行-32 * 256,给出-8192。将其转换为 unsigned short 得到 65536 - 8192 = 57344


如果您尝试从第一个示例中获取224,最简单的方法是使用 unsigned char 而不是 char 。 然后myChar[0]将保存值224而不是值-32

使用无符号类型进行位级操作。

例如,在具有 8 位字节的计算机上,并且char 是有符号的,myChar[0] = 0xE0会导致负值。在表达式中使用时,这是符号扩展

相反,为了避免出现问题,请对数字使用有符号类型。

当您将字符存储到 myChar 中时,您将它存储为大端序:首先是高字节,然后是低字节。 当您读出单个字节时,您将它们作为小端序读取:低字节优先,高字节第二(移位 8,或乘以 256(。 这就是为什么你会得到这么大的价值。

myShort = (myChar[0] * 256) + myChar[1];

会给你预期的答案。