2012-09-02 81 views
10

我有一個unsigned char數組[248];填充字節。就像2F AF FF 00 EB AB CD EF ..... 這個數組是我的字節流,我將數據從UART(RS232)存儲爲緩衝區。將字節轉換爲C中的Int/uint

現在我想將字節轉換回我的uint16和int32's。

在C#中,我使用了BitConverter類來做到這一點。例如:

byte[] Array = { 0A, AB, CD, 25 }; 
int myint1 = BitConverter.ToInt32(bytes, 0); 
int myint2 = BitConverter.ToInt32(bytes, 4); 
int myint3 = BitConverter.ToInt32(bytes, 8); 
int myint4 = BitConverter.ToInt32(bytes, 12); 
//... 
enter code here 
Console.WriteLine("int: {0}", myint1); //output Data... 

C中是否有類似的函數? (無.NET,我用的是KEIL編譯,因爲代碼運行在一個微控制器)

與問候 山姆

解決方案: 方式)

,我首先得轉換或初始化數組一個uint8_t ARRAY [248]; 然後我用這個代碼在您的幫助:

uint32_t* myint1 = (uint32_t *)&RXBUFF[2]; //test 
uint16_t* myint2 = (uint16_t *)&RXBUFF[6]; //test3 

注意: 十六進制的int值「1985」被myint2表示爲0x07C1。我發送的字節是「C1 07」,因此微控制器正在更改字節順序

我也將測試其他方法。

WR山姆:)

回答

8

是的。假設你的字節在:

uint8_t bytes[N] = { /* whatever */ }; 

我們知道,一個16位整數只是兩個8位整數連接,即一個具有256的倍數或可替代地是由8位移:

uint16_t sixteen[N/2]; 

for (i = 0; i < N; i += 2) 
    sixteen[i/2] = bytes[i] | (uint16_t)bytes[i+1] << 8; 
      // assuming you have read your bytes little-endian 

類似地,對於32位:

uint32_t thirty_two[N/4]; 

for (i = 0; i < N; i += 4) 
    thirty_two[i/4] = bytes[i] | (uint32_t)bytes[i+1] << 8 
     | ((uint32_t)bytes[i+2] << 16 | (uint32_t)bytes[i+3] << 24; 
      // same assumption 

如果字節被讀大端,你當然顛倒順序:

bytes[i+1] | (uint16_t)bytes[i] << 8 

bytes[i+3] | (uint32_t)bytes[i+2] << 8 
    | (uint32_t)bytes[i+1] << 16 | (uint32_t)bytes[i] << 24 

請注意,存儲整數中的字節順序與正在運行的體系結構的字節順序之間存在差異。在這個答案中引用的序列號是存儲的整數,即bytes的內容。自從endian-ness is taken care of when shifting以來,解決方案獨立於運行架構的端序。

+0

如果它的大端是什麼? – Sam

+0

然後你移入最低有效位而不是最高有效位。 – devsnd

+0

@twall,我認爲你的意思是字節。 –

15

有沒有標準函數來爲你做它在C.你必須裝配字節回到您的16位和32位整數自己。小心endianness!

這裏有一個簡單的小端例如:

extern uint8_t *bytes; 
uint32_t myInt1 = bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24); 

對於大端系統,它只是順序相反:

uint32_t myInt1 = (bytes[0] << 24) + (bytes[1] << 16) + (bytes[2] << 8) + bytes[3]; 

您也許能矇混過關:

uint32_t myInt1 = *(uint32_t *)bytes; 

如果您對齊問題非常小心。

+1

在移動它之前,我會將每個'bytes []''轉換爲'uint32_t'。如上所述,在執行轉換之前,它們將被轉換爲「int」,但「int」不必是32位。 –

+0

這將是最安全的,同意。 –

+0

假設'字節'是本機端,你會遇到什麼樣的對齊問題?或者,我想,什麼樣的情況會使對齊成爲一個問題? – Azmisov

6

你可以直接從你的數組中創建一個uint16_t *指針。

uint8_t bytes[N] = { /* whatever */ }; //Shamelessly stolen from Shanbaz 

uint16_t* viewAsUint16_t = (uint16_t *)&bytes[0]; 

現在你可以使用你的指針來訪問元素。

請注意,這假定您的機器的端點是正確的。您可能需要遍歷這些uint16_t,並使用像ntohs這樣的函數(在大多數操作系統上應該可用)來糾正不一致性。

+0

我現在就試試這個。 – Sam

+0

我試過你的代碼,但它似乎沒有奏效。 我將調試器和控制檯的輸出保存爲圖片:[link](http://s18.postimage.org/fipv7svp3/debugbyte.png) – Sam

0
  char letter = 'A'; 
      size_t filter = letter; 
      filter = (filter << 8 | filter); 
      filter = (filter << 16 | filter); 
      filter = (filter << 32 | filter); 
      printf("filter: %#I64x \n", filter); 

結果: 「過濾器:0x4141414141414141」

0

在小端的情況下,你就不能使用memcpy?

memcpy((char*)&myint1, aesData.inputData[startindex], length);