下面的代码是从字符中提取ASCII码。 当我在普通的ASCII区域中转换字符时,我得到了我期望的值。 当我从扩展区域转换£和€时,我得到一个1的填充INT,我正在存储该字符。
e.g。以下输出是:
45(ascii E如预期的那样) FFFFFF80(按预期延长的ascii€,但填充了一些)
这不是一个问题,但我只是想知道为什么会这样。 这是代码......
unsigned int asciichar[3];
string cTextToEncode = "E€";
for (unsigned int i = 0; i < cTextToEncode.length(); i++)
{
asciichar[i] = (unsigned int)cTextToEncode[i];
cout << hex << asciichar[i] << "\n";
}
任何人都能解释为什么会这样吗? 感谢
答案 0 :(得分:7)
取决于实现,char可以是signed或unsigned。在你的情况下,它们似乎是有符号的,所以0x80被解释为-128而不是128,因此当转换为整数时它变为0xffffff80。
顺便说一句,这与ASCII
完全没有关系答案 1 :(得分:5)
首先,ASCII(扩展或其他)中没有€,因为创建ASCII时欧元不存在。但是,几个支持ASCII的8位编码确实支持€字符,但是转换是由源代码编辑器完成的(编译器只看到一个字节恰好代表编辑器中的€,但可能完全是其他东西,比如,以色列的一台电脑。)
其次,(unsigned int)
强制转换不提取字符的ASCII编码。它们只是将基础数字char
类型的值转换为无符号整数。当转换后的值为负时,这会导致奇怪的事情发生 - 在编译器上,char
恰好是signed char
,因此ASCII值大于127的字符最终为负char
值
您应首先转换为unsigned char
,然后转换为unsigned int
。
答案 2 :(得分:1)
在宣传签名值时应该小心。
当将signed char提升为signed int时,会考虑第一位(符号位)。该算法大致如下所示:
1)如果你有1X-XX-XX-XX
(二进制中的字符,X - 任何二进制数字)那么int将是(以24开始)1...1-1X-XX-XX-XX
(二进制) - &gt; 0xFFFFFFYY
(十六进制)
2)如果你有0X-XX-XX-XX
(二进制),那么你将拥有(以24个零开始)0...0-0X-XX-XX-XX
(二进制) - &gt; 0x000000YY
(十六进制)。
在您的情况下,您希望始终强制执行规则#2。为此,您需要告诉编译器忽略第一位(符号位)。为此,您需要使用unsigned char。