阅读评论后,感谢@MM和@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
因此,我有一个从文件中读取的两个字节的值,想要转换为无符号的short,以便可以使用该数值。
示例代码:
#include <iostream>
int main() {
char myChar[2];
myChar[1] = 'à';
myChar[0] = '\0';
unsigned short myShort;
myShort = ((myChar[1] << 8) | (myChar[0]));
std::cout << myShort << std::endl;
return 0;
}
输出:
40960
但是à\0
还是E0 00
应该将224的值作为无符号的两个字节的值?
也很有趣...
这段代码:
include <iostream>
int main() {
char * myChar;
myChar = "\0à";
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
(在您的系统上)的范围是-128
到127
。这很常见。你写myChar[0] = 224;
。(0xE0
是int
带有值的文字224
)。
这是超出范围的转换,导致实现定义的行为。最常见的是,实现将定义此值以对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
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句