2015-03-30 66 views
0

我搜遍了很多网站,似乎无法找到任何相关的东西。使用无符号字符数组处理单个字节

我希望能够获取每个默认数据类型的单个字节,如short,unsigned short,int,unsigned int,float和double,并将每个单独的字节信息(二进制部分)存储到每个索引的unsigned char数组。这怎么能实现?

例如:

int main() { 
    short sVal = 1; 
    unsigned short usVal = 2; 
    int iVal = 3; 
    unsigned int uiVal = 4; 
    float fVal = 5.0f; 
    double dVal = 6.0; 

    const unsigned int uiLengthOfShort = sizeof(short); 
    const unsigned int uiLengthOfUShort = sizeof(unsigned short); 
    const unsigned int uiLengthOfInt = sizeof(int); 
    const unsigned int uiLengthOfUInt = sizeof(unsigned int); 
    const unsigned int uiLengthOfFloat = sizeof(float); 
    const unsigned int uiLengthOfDouble = sizeof(double); 

    unsigned char ucShort[uiLengthOfShort]; 
    unsigned char ucUShort[uiLengthOfUShort]; 
    unsigned char ucInt[uiLengthOfInt]; 
    unsigned char ucUInt[uiLengthOfUInt]; 
    unsigned char ucFloat[uiLengthOfFloat]; 
    unsigned char ucDouble[uiLengthOfDouble]; 

    // Above I declared a variable val for each data type to work with 
    // Next I created a const unsigned int of each type's size. 
    // Then I created unsigned char[] using each data types size respectively 
    // Now I would like to take each individual byte of the above val's 
    // and store them into the indexed location of each unsigned char array. 

    // For Example: - I'll not use int here since the int is 
    // machine and OS dependent. 
    // I will use a data type that is common across almost all machines. 
    // Here I will use the short as my example 

    // We know that a short is 2-bytes or has 16 bits encoded 
    // I would like to take the 1st byte of this short: 
    // (the first 8 bit sequence) and to store it into the first index of my unsigned char[]. 
    // Then I would like to take the 2nd byte of this short: 
    // (the second 8 bit sequence) and store it into the second index of my unsigned char[]. 

    // How would this be achieved for any of the data types? 

    // A Short in memory is 2 bytes here is a bit representation of an 
    // arbitrary short in memory { 0101 1101, 0011 1010 } 
    // I would like ucShort[0] = sVal's { 0101 1101 } & 
    //    ucShort[1] = sVal's { 0011 1010 } 

    ucShort[0] = sVal's First Byte info. (8 Bit sequence) 
    ucShort[1] = sVal's Second Byte info. (8 Bit sequence) 

    // ... and so on for each data type. 

    return 0; 
} 
+0

你怎么知道没有任何系统的短32位? – immibis 2015-03-30 18:30:25

+0

阅读工会。不确定每个默认数据类型的单个字节是什么意思。 – 2015-03-30 18:33:13

+0

我说大多数机器的短小是2个字节。这并不意味着全部,但它更可能是2bytes,然后使用可能是16bits(2bytes-obsolete),32bits(x86上通用4bytes)和64bits(64bit-common上64bit机器)的整数。 – 2015-03-30 18:34:12

回答

1

好了,先不要做,如果你能避免它。它的危险性可能非常依赖于建筑。

上面的评论者是正确的,union是最安全的方法,你仍然有endian问题,是的,但至少你没有堆栈对齐问题(我认为这是网络代码,所以堆叠排列是另一个潜在的架构问题)

这就是我发现这样做的最直接的方式:

uint32_t example_int; 
char array[4]; 

//No endian switch 
array[0] = ((char*) &example_int)[0]; 
array[1] = ((char*) &example_int)[1]; 
array[2] = ((char*) &example_int)[2]; 
array[3] = ((char*) &example_int)[3]; 

//Endian switch 
array[0] = ((char*) &example_int)[3]; 
array[1] = ((char*) &example_int)[2]; 
array[2] = ((char*) &example_int)[1]; 
array[3] = ((char*) &example_int)[0]; 

如果你想编写跨架构的代码,您将需要以某种方式处理endian问题。我的建议是构建一个短序列测试,并根据上述方法构建函数来“打包”和“解压缩”字节数组。应该注意的是,要“解包”一个字节数组,只需颠倒上述赋值语句即可。

+0

谢谢你,但我也发现这个http://www.cplusplus.com/forum/articles/12/也接近我正在寻找,但不知道是否endian或对齐仍然是一个问题。 – 2015-03-30 19:42:02

+0

我打算使用这种类型的算法来获取各种数据类型,并将它们存储到unsigned char []或unsigned char *中,然后将内容保存到二进制文件中。这里没有直接压缩,而是一种将数据打包成一种文件读/写类的工作方式。文件内容将被存储为一串无符号字符数组,但字节数据将来自游戏引擎的数据,例如位置,像素,播放器等。然后,通过网络传输将很容易处理该文件的格式。 – 2015-03-31 00:58:25

0

在Raw N的帮助下,我提供了一个网站,我对字节操作进行了搜索,发现了这个线程 - http://www.cplusplus.com/forum/articles/12/,它提供了一个类似的解决方案,但我不得不重复这个过程为每个默认的数据类型。

1

最简单的正确的方法是:

// static_assert(sizeof ucShort == sizeof sVal); 

memcpy(&ucShort, &sVal, sizeof ucShort); 

您在留言写的东西是不正确的;除字符类型外,所有类型都具有与机器相关的大小。

0

经过一番测试,这是我到目前为止所提出的,这取决于机器架构,但是在其他机器上这样做的概念是相同的。

typedef struct packed_2bytes { 
    unsigned char c0; 
    unsigned char c1; 
} packed_2bytes; 

typedef struct packed_4bytes { 
    unsigned char c0; 
    unsigned char c1; 
    unsigned char c2; 
    unsigned char c3; 
} packed_4bytes; 

typedef struct packed_8bytes { 
    unsigned char c0; 
    unsigned char c1; 
    unsigned char c2; 
    unsigned char c3; 
    unsigned char c4; 
    unsigned char c5; 
    unsigned char c6; 
    unsigned char c7; 
} packed_8bytes; 

typedef union { 
    short s; 
    packed_2bytes bytes; 
} packed_short; 

typedef union { 
    unsigned short us; 
    packed_2bytes bytes; 
} packed_ushort; 

typedef union { // 32bit machine, os, compiler only 
    int i; 
    packed_4bytes bytes; 
} packed_int; 

typedef union { // 32 bit machine, os, compiler only 
    unsigned int ui; 
    packed_4bytes bytes; 
} packed_uint; 

typedef union { 
    float f; 
    packed_4bytes bytes; 
} packed_float; 

typedef union { 
    double d; 
    packed_8bytes bytes; 
} packed_double; 

没有实现只使用这些类型的声明或定义。我认为他们应该包含哪个endian被使用,但是使用它们的人必须提前知道这一点,就像知道每种默认类型的机器体系结构的大小一样。我不确定是否会因int,signed或bit实现而导致signed int问题,但也可能需要考虑。

相关问题