代码之家  ›  专栏  ›  技术社区  ›  Jader Dias

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

  •  5
  • Jader Dias  · 技术社区  · 15 年前

    我使用的是DSPIC33F(16位微控制器);

    • 如何转换 char[] int[] 这样,每两个字符变成一个int使用C++?
    • 逆运算呢?
    6 回复  |  直到 15 年前
        1
  •  3
  •   Mud    15 年前
    int* intArray = new int[sizeOfByteArray];
    
    for (int i=0; i<sizeOfByteArray; ++i)
       intArray[i] = byteArray[i];
    

    std::copy(byteArray, byteArray+sizeofByteArray, intArray);
    
        2
  •  1
  •   Jader Dias    15 年前

    我想你想把字节组合成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};
    }
    

    只要您知道变量的长度,这个逻辑就可以使用任何转换格式。

        3
  •  0
  •   bobasaurus    15 年前

    我假设您的char数组包含字节(而不是实际的ASCII字符),您希望将其转换为16位有符号整数。下面的函数将用于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]);
        }
    

    }

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

    
    typedef unsigned short uint16_t;
    typedef signed short int16_t;
    typedef unsigned char uint8_t;
    
    
        4
  •  0
  •   janm    15 年前

    在DSPIC33上,我怀疑你使用的是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];
        }
    }
    
        5
  •  0
  •   Vovanium    15 年前

    我不确定你的字节是char还是octet。您可能已经有了两个用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++模式下编译。您可以用CHISTE和CSTDDDEF替换Case.h和StDeff.h,以实现更严格的C++一致性。

    • 注意:如果2个字节不能放入int中,则此代码将不起作用。请检查此项。int中的位数不应小于2*字节\位,否则将丢失一个字符。如果您的意思是“byte”下的8位八位字节,您可以将byte-bit定义中的char-bit更改为8位,然后16位int将正确匹配八位字节。

    实施注意事项:

    ((1<<BYTE_BIT)-1)
    

    是n个低位的位掩码,其中n=字节\位。它等于

        /--N--\
    ...011...11 (binary)
    
        6
  •  -1
  •   Alien_SM    15 年前

    以下是编译和测试方法:

    #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;
    }
    

    这个 按内部安排 接受5个参数并返回实际转换数组的大小,如果传入,这很方便 输出数组 这比实际转换后的大小要大,同时也是一种提取错误的方法。

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

    我只是使用printf测试过程,我知道在嵌入式硬件中使用它通常需要分配代码空间。我只是包含了endian交换,以确保您能够看到在这两种情况下需要做什么,但是在实际的实现中可以很容易地删除这一点。

    按内部安排 但这样很容易理解。