我有一串 256*4 字节的数据。这 256*4 个字节需要转换成 256 个无符号整数。它们出现的顺序是小端,即字符串中的前四个字节是第一个整数的小端表示,接下来的四个字节是下一个整数的小端表示,依此类推。
解析这些数据并将这些字节合并为无符号整数的最佳方法是什么?我知道我必须使用位移运算符,但我不知道以什么方式。
我有一串 256*4 字节的数据。这 256*4 个字节需要转换成 256 个无符号整数。它们出现的顺序是小端,即字符串中的前四个字节是第一个整数的小端表示,接下来的四个字节是下一个整数的小端表示,依此类推。
解析这些数据并将这些字节合并为无符号整数的最佳方法是什么?我知道我必须使用位移运算符,但我不知道以什么方式。
希望这可以帮助你
unsigned int arr[256];
char ch[256*4] = "your string";
for(int i = 0,k=0;i<256*4;i+=4,k++)
{
arr[k] = ch[i]|ch[i+1]<<8|ch[i+2]<<16|ch[i+3]<<24;
}
或者,我们可以使用 C/C++ 转换将 char 缓冲区解释为 unsigned int 数组。这可以帮助摆脱移位和字节序依赖。
#include <stdio.h>
int main()
{
char buf[256*4] = "abcd";
unsigned int *p_int = ( unsigned int * )buf;
unsigned short idx = 0;
unsigned int val = 0;
for( idx = 0; idx < 256; idx++ )
{
val = *p_int++;
printf( "idx = %d, val = %d \n", idx, val );
}
}
这将打印出 256 个值,第一个是 idx = 0, val = 1684234849(所有剩余的数字 = 0)。
作为旁注,“abcd”转换为 1684234849,因为它在 X86(Little Endian)上运行,其中“abcd”为 0x64636261(“a”为 0x61,“d”为 0x64 - 在 Little Endian 中,LSB 为在最小的地址)。所以 0x64636261 = 1684234849。
另请注意,如果使用 C++,则应在这种情况下使用reinterpret_cast :
const char *p_buf = "abcd";
const unsigned int *p_int = reinterpret_cast< const unsigned int * >( p_buf );
如果您的主机系统是 little-endian,只需读取 4 个字节,正确移动并将它们复制到 int
char bytes[4] = "....";
int i = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
如果您的主机是大端的,请执行相同操作并反转 int 中的字节,或者在使用位移位复制时即时反转它,即只需将索引bytes[]
从 0-3 更改为 3-0
但是,如果您的 PC 是 little-endian,您甚至不应该这样做,只需将整个 char 数组复制到 int 数组
#define LEN 256
char bytes[LEN*4] = "blahblahblah";
unsigned int uint[LEN];
memcpy(uint, bytes, sizeof bytes);
也就是说,最好的方法是完全避免复制并为两种类型使用相同的数组
union
{
char bytes[LEN*4];
unsigned int uint[LEN];
} myArrays;
// copy data to myArrays.bytes[], do something with those bytes if necessary
// after populating myArrays.bytes[], get the ints by myArrays.uint[i]