如何将字节数组转换为int数组?

时间:2010-11-12 01:26:25

标签: c microcontroller

我正在使用dsPic33F(16位微控制器);

  • 如何将char[]转换为int[],以便每两个字符使用C ++成为一个int?
  • 和逆操作?

6 个答案:

答案 0 :(得分:3)

int* intArray = new int[sizeOfByteArray];

for (int i=0; i<sizeOfByteArray; ++i)
   intArray[i] = byteArray[i];

或者

std::copy(byteArray, byteArray+sizeofByteArray, intArray);

答案 1 :(得分:1)

我想你想把字节组合成int?

您需要做的是在创建int时移位位

(oki这是java,因为我这里没有我的C ++代码)

public static final int byteArrayToInt(byte [] b) {
    return (b[0] << 24)
            + ((b[1] & 0xFF) << 16)
            + ((b[2] & 0xFF) << 8)
            + (b[3] & 0xFF);
}

public static final byte[] intToByteArray(int value) {
    return new byte[] {
            (byte)(value >>> 24),
            (byte)(value >>> 16),
            (byte)(value >>> 8),
            (byte)value};
}

只要您知道变量的长度

,此逻辑就适用于任何转换格式

答案 2 :(得分:0)

我假设您的char数组包含要转换为16位有符号整数的字节(而不是实际的ascii字符)。下面的函数适用于MSB第一个字节排序。我在这里使用无符号字符来表示字节输入(uint8_t)。

void BytesToInts(uint8_t *byteArray, uint16_t byteArraySize, int16_t *intArray, uint16_t intArraySize) {

    //do some error checking on the input
    if (byteArraySize == 0) return;
    if (intArraySize != (byteArraySize/2)) return;

    //convert each pair of MSB-first bytes into a signed 16-bit integer
    for (uint16_t i=0; i<intArraySize; i++)
    {
        intArray[i] = (int16_t) ((byteArray[i<<1]<<8) | byteArray[(i<<1)+1]);
    }

//do some error checking on the input if (byteArraySize == 0) return; if (intArraySize != (byteArraySize/2)) return; //convert each pair of MSB-first bytes into a signed 16-bit integer for (uint16_t i=0; i<intArraySize; i++) { intArray[i] = (int16_t) ((byteArray[i<<1]<<8) | byteArray[(i<<1)+1]); }

如果您需要整数定义,可以使用以下内容:

}

答案 3 :(得分:0)

在dsPIC 33F上,我怀疑你是在使用C ++。如果您使用的是C ++,那么您使用的编译器是什么,以及您拥有多少运行时库? (你从哪里得到它!)

如果字节顺序正确,如果需要副本,可以使用memcpy(),或者如果只想使用缓冲区中的16位数字并且对齐正常,则只需转换指针。如果您正在管理缓冲区,在这样的平台上使用union来满足此类要求并不罕见:

union my_buffer {
    unsigned char char_buf[128];
    int int_buf[64];
};

在处理字符时通过char_buf访问,在处理int时通过int_buf访问。

如果需要交换字节,只需实现swab()的变体并使用它代替memcpy(),就像其他答案一样,或者像这样的代码:

void doit(int16_t* dest, char const* src, size_t word_count)
{
    char* const end = (char*) (dest + word_count);
    char* p;

    for (p = (char*) dest; p != end; src += 2, p += 2) {
        p[0] = src[1];
        p[1] = src[0];
    }
}

答案 4 :(得分:0)

我不确定你的字节是字符还是八位字节。您可能已经在dsPIC的16位字中用两个八位字节打包,因此您无需再打包它们。

#include <limits.h>
#include <stddef.h>

#define BYTE_BIT CHAR_BIT /* Number of significant bits in your 'byte' * Read note below */

/* pack routine */
void ipackc(int *packed, const char *unpacked, size_t nints) {
    for(; nints>0; nints--, packed++, unpacked += 2) {
        *packed = (unpacked[0]<<BYTE_BIT) | (unpacked[1] & ((1<<BYTE_BIT)-1));
    }
}

/* unpack routine */
void cunpacki(char *unpacked, const int *packed, size_t nints) {
    for(; nints>0; nints--, packed++, unpacked += 2) {
        unpacked[0] = *packed>>BYTE_BIT;
        unpacked[1] = *packed & ((1<<BYTE_BIT)-1);
    }
}

这是一个C代码,但没有什么可以处理C ++功能。它可以在C ++模式下编译。您可以使用climits和cstddef替换limits.h和stddef.h以获得更严格的C ++一致性。

  • 注意:如果您的'bytes'不能适合int,则此代码将不起作用。检查一下。 int中的位数应不小于2 * BYTE_BIT或其中一个字符将丢失。如果你的意思是'byte'下的8位八位字节,你可以将BYTE_BIT定义中的CHAR_BIT改为8,然后16位int将正确地适合八位字节。

关于实施的说明:

((1<<BYTE_BIT)-1)

是N个低位的位掩码,其中N = BYTE_BIT。它等于

    /--N--\
...011...11 (binary)

答案 5 :(得分:-1)

这是一个经过编译和测试的方法:

#include <stdio.h>

unsigned short ByteToIntArray( 
        unsigned char inByteArray[], 
        unsigned short inArraySize, 
        unsigned short outWordArray[], 
        unsigned short outArraySize, 
        unsigned char swapEndian
    )
{
    if (    ( inArraySize/2 > outArraySize )
         || ( outArraySize == 0 ) 
         || ( inArraySize == 0 )
       )
    {
        return -1;        
    }

    unsigned short i;

    if ( swapEndian == 0 )
    {    
        for ( i = 0; i < outArraySize; ++i )
        {
            outWordArray[ i ] = ( (unsigned short)inByteArray[ i*2 ] << 8 ) + inByteArray[ i*2 + 1 ];
        }
    }
    else
    {
        for ( i = 0; i < outArraySize; ++i )
        {
            outWordArray[ i ] = ( (unsigned short)inByteArray[ i*2 + 1 ] << 8 ) + inByteArray[ i*2 ];
        }
    }
    return i;    
}


int main(){
    unsigned char ucArray[ 16 ] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
    unsigned short usArray[ 8 ];
    unsigned short size;

     // "/ 2" on the usArray because the sizes are the same in memory
     size = ByteToIntArray( ucArray, sizeof( ucArray ), usArray, sizeof( usArray ) / 2, 0 );

    if( size > 0 )
    {
        printf( "Without Endian Swapping:\n" );
        for( unsigned char i = 0; i < size ; ++i )
        {
            printf( "0x%04X ", usArray[ i ] );
        }
        printf( "\n" );
    }

    if( size > 0 )
    {
         // "/ 2" on the usArray because the sizes are the same in memory
        size = ByteToIntArray( ucArray, sizeof( ucArray ), usArray, sizeof( usArray ) / 2, 1 );

        printf( "With Endian Swapping:\n" );
        for( unsigned char i = 0; i < size ; ++i )
        {
            printf( "0x%04X ", usArray[ i ] );
        }
        printf( "\n" );
    }
    return 0;
}

ByteToIntArray 获取5个参数并返回实际转换数组的大小,如果传入的 outWordArray 大于实际转换后的大小,则此方便同时也是一种收集错误的方法。

一个简单的逐位移位运算符和+用于将两个字节组合成一个字。

我刚用printf来测试程序,我知道在嵌入式硬件中使用它通常需要大量的代码空间。我只是包含了Endian交换,以确保您可以在两种情况下看到您需要做什么,但这可以在实际实现中轻松删除。

ByteToIntArray 例程中还有很多优化空间,但这种方式很容易理解。