简体   繁体   中英

How to pack data in binary format in c++

Say, i have binary protocol, where first 4 bits represent a numeric value which can be less than or equal to 10 (ten in decimal).

In C++, the smallest data type available to me is char, which is 8 bits long. So, within my application, i can hold the value represented by 4 bits in a char variable. My question is, if i have to pack the char value back into 4 bits for network transmission, how do i pack my char's value back into 4 bits?

You do bitwise operation on the char;

so

  unsigned char packedvalue = 0;

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

Set the 4 upper most bit to 7 and the lower 4 bits to 10

Unpacking these again as

 int upper, lower;

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

As an extra answer to the question -- you may also want to look at protocol buffers for a way of encoding and decoding data for binary transfers.

Sure, just use one char for your value:

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"

The lower 4 bits will be left at zero. If they're also used for something, you'll have to populate c fully before writing it. To read:

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

Well, there's the popular but non-portable "Bit Fields". They're standard-compliant, but may create a different packing order on different platforms. So don't use them.

Then, there are the highly portable bit shifting and bitwise AND and OR operators, which you should prefer. Essentially, you work on a larger field (usually 32 bits, for TCP/IP protocols) and extract or replace subsequences of bits. See Martin's link and Soren's answer for those.

Are you familiar with C's bitfields ? You simply write

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

Be warned, various operations are slower on bitfields because the compiler must unpack them for things like addition. I'd imagine unpacking a bitfield will still be faster than the addition operation itself, even though it requires multiple instructions, but it's still overhead. Bitwise operations should remain quite fast. Equality too.

You must also take care with endianness and threads (see the wikipedia article I linked for details, but the issues are kinda obvious). You should leearn about endianness anyways since you said "binary protocol" (see this previous questions )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM