Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Writing 'bits' to C++ file streams

How can I write 'one bit' into a file stream or file structure each time?

Is it possible to write to a queue and then flush it?

Is it possible with C# or Java?

This was needed when trying to implement an instance of Huffman coding. I can't write bits into files, so write them to a bitset and then (when compression was completed) write 8-bit piece of it each time (exclude last one).

like image 998
sorush-r Avatar asked Mar 19 '10 11:03

sorush-r


2 Answers

Buffering the individual bits until you've accumulated a whole byte seems like a good idea:

byte b;
int s;

void WriteBit(bool x)
{
    b |= (x ? 1 : 0) << s;
    s++;

    if (s == 8)
    {
        WriteByte(b);
        b = 0;
        s = 0;
    }
}

You just have to deal with the case when the number of bits to be written is not a multiple of eight.

like image 156
dtb Avatar answered Oct 06 '22 09:10

dtb


You can use boost::dynamic_bitset along with std::ostream_iterator to achieve the desired result in a concise manner:

#include <fstream>
#include <iterator>
#include <boost/dynamic_bitset.hpp>

typedef boost::dynamic_bitset<unsigned char> Bitset;

// To help populate the bitset with literals */
Bitset& operator<<(Bitset& lhs, bool val) {lhs.push_back(val); return lhs;}

int main()
{
    Bitset bitset;
    bitset<<0<<1<<0<<1<<0<<1<<0<<1
          <<1<<0<<1<<0;

    std::ofstream os("data.dat", std::ios::binary);
    std::ostream_iterator<char> osit(os);
    boost::to_block_range(bitset, osit);

    return 0;
}

I made the block size of my dynamic_bitset 8 bits by specifying unsigned char as the template parameter. You can make the block size bigger by specifying a larger integer type.

boost::to_block_range dumps the bitset in blocks to the given output iterator. If there are empty remainder bits in the last block, they'll be padded with zero.

When I open data.dat in a hex editor I see: AA 05. This is on a little endian platform (x64).

like image 42
Emile Cormier Avatar answered Oct 06 '22 08:10

Emile Cormier