4

I'm working on Huffman coding and I have built the chars frequency table with a

std::map<char,int> frequencyTable;

Then I have built the Huffman tree and then i have built the codes table in this way:

std::map<char,std::vector<bool> > codes;

Now I would read the input file, character by character ,and encode them through the codes table but i don't know how write bits into a binary output file. Any advice?

UPDATE: Now i'm trying with these functions:

void Encoder::makeFile()
{
char c,ch;
unsigned char ch2;
while(inFile.get(c))
{
    ch=c;
    //send the Huffman string to output file bit by bit
    for(unsigned int i=0;i < codes[ch].size();++i)
    {
        if(codes[ch].at(i)==false){
            ch2=0;
        }else{
            ch2=1;
        }
        encode(ch2, outFile);
    }
}
ch2=2; // send EOF
encode(ch2, outFile);

inFile.close();
outFile.close();
}

and this:

void Encoder::encode(unsigned char i, std::ofstream & outFile)
{
int bit_pos=0; //0 to 7 (left to right) on the byte block
unsigned char c; //byte block to write

if(i<2) //if not EOF
{
    if(i==1)
        c |= (i<<(7-bit_pos)); //add a 1 to the byte
    else //i==0
        c=c & static_cast<unsigned char>(255-(1<<(7-bit_pos))); //add a 0
    ++bit_pos;
    bit_pos%=8;
    if(bit_pos==0)
    {
        outFile.put(c);
        c='\0';
    }
}
else
{
    outFile.put(c);
}
}

but ,I don't know why ,it doesn't work, the loop is never executed and the encode function is never used, why?

Alfredo Liardo
  • 115
  • 2
  • 2
  • 10
  • 2
    As there are only 256 possible char values, consider creating an array of 256 instead of a map with char as the key. This may use additional memory if only a few possible chars are used, but will be much faster than map look up. – Neil Kirk Feb 13 '15 at 15:12
  • This is a project for school and my main goal is to make the program work, because, unfortunately, I have little time left – Alfredo Liardo Feb 13 '15 at 15:30

2 Answers2

5

You can't write a single bit directly to a file. The I/O unit of reading/writing is a byte (8-bits). So you need to pack your bools into chunks of 8 bits and then write the bytes. See Writing files in bit form to a file in C or How to write single bits to a file in C for example.

Community
  • 1
  • 1
Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
0

The C++ Standard streams support an access of the smallest unit the underlying CPU supports. That's a byte.

There are implementation of a bit stream class in C++ like the Stanford Bitstream Class.

Another approach could use the std::bitset class.

harper
  • 13,345
  • 8
  • 56
  • 105