2012-09-02 40 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);