如何在c ++中打包二进制格式的数据

时间:2012-01-16 22:46:14

标签: c++ binary-data

说,我有二进制协议,前4位代表一个数值,可以小于或等于10(十进制十进制)。

在C ++中,我可用的最小数据类型是char,它是8位长。因此,在我的应用程序中,我可以在char变量中保存由4位表示的值。我的问题是,如果我必须将char值打包回4位用于网络传输,我如何将我的char的值打包回4位?

4 个答案:

答案 0 :(得分:4)

您对char执行按位操作;

所以

  unsigned char packedvalue = 0;

  packedvalue |= 0xF0 & (7 <<4);
  packedvalue |= 0x0F & (10);

将最高4位设置为7,将低4位设置为10

再次打开包装

 int upper, lower;

 upper = (packedvalue & 0xF0) >>4;
 lower = packedvalue & 0x0F;

作为问题的额外答案 - 您可能还想查看protocol buffers以获取二进制传输数据的编码和解码方法。

答案 1 :(得分:3)

当然,只需使用一个字符值即可:

std::ofstream outfile("thefile.bin", std::ios::binary);

unsigned int n;  // at most 10!
char c = n << 4; // fits
outfile.write(&c, 1);  // we wrote the value "10"

低4位将保留为零。如果它们也被用于某些东西,那么在编写之前你必须完全填充c。阅读:

infile.read(&c, 1);
unsigned int n = c >> 4;

答案 2 :(得分:3)

嗯,有流行但不便携的“比特场”。它们符合标准,但可能在不同平台上创建不同的包装顺序。所以不要使用它们。

然后,有一个高度便携的位移和按位AND和OR运算符,您应该更喜欢。本质上,您在更大的字段(通常是32位,用于TCP / IP协议)上工作,并提取或替换位的子序列。请参阅Martin的链接和Soren的答案。

答案 3 :(得分:0)

您熟悉C's bitfields吗?你只需写

struct my_bits {
  unsigned v1 : 4;
  ...
};

请注意,位域上的各种操作速度较慢,因为编译器必须解压缩它们以进行添加。我想,解压缩一个位域仍然比加法操作本身更快,即使它需要多个指令,但它仍然是开销。按位运算应该保持很快。平等也是。

您还必须注意字节顺序和线程(请参阅我链接的维基百科文章以获取详细信息,但问题显而易见)。无论如何你都应该了解有关字节序的内容,因为你说过#bin; binary protocol&#34; (见this previous questions