[英]Error converting char[2] to unsigned short?
閱讀評論后,感謝@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
是一個具有值224
的int
文字)。
這是超出范圍的轉換 ,導致實現定義的行為 。 最常見的是,實現會將其定義為以256為模,直到該值在范圍內。 因此,您最終得到與以下結果相同的結果:
myChar[0] = -32;
然后計算(myChar[1] << 8) | myChar[0]
(myChar[1] << 8) | myChar[0]
為0 | (-32)
0 | (-32)
,即-32
。 最后,您將轉換為unsigned short
。 這是另一次超出范圍的轉換 ,因為系統上unsigned short
的范圍是[0, 65535]
。
但是,在這種情況下,為了將模數調整為65536
,定義為無符號類型的超范圍轉換是明確定義的,因此結果為65536-32 = 65504
。
顛倒順序執行((-32) << 8) | 0
((-32) << 8) | 0
。 左移負值會導致不確定的行為 ,盡管在您的系統上它表現為-32 * 256
,為-8192
。 將其轉換為unsigned short
會得到57344
= 57344
。
如果您嘗試從第一個示例中獲取224
,最簡單的方法是使用unsigned char
而不是char
。 然后, myChar[0]
將保留值224
而不是值-32
。
使用無符號類型進行位級別操作。
例如,在具有8位字節且對char
進行簽名的計算機上, myChar[0] = 0xE0
得出負值。 在表達式中使用時會擴展符號 。
相反,為避免出現問題,請對數字使用帶符號的類型。
當您將字符存儲到myChar
,您將其存儲為big-endian:首先是高字節,然后是低字節。 當您讀取各個字節時,您將它們讀取為低位字節序:低位在前,高位在后(移位8,或乘以256)。 這就是為什么您獲得如此高的價值。
myShort = (myChar[0] * 256) + myChar[1];
將給您預期的答案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.