簡體   English   中英

將char [2]轉換為unsigned short時出錯?

[英]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

但是à\\0E0 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的范圍(在您的系統上)是-128127 這很常見。 您編寫myChar[0] = 224; 0xE0是一個具有值224int文字)。

這是超出范圍的轉換 ,導致實現定義的行為 最常見的是,實現會將其定義為以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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM