If you're writing/reading a tree to store header information (using a pre-order traversal) you must be careful. You CANNOT write code like this:
Tree * read(ibstream& input)
{
int val;
input.readbits(1,val);
if (val == 0) { // internal node
return new Tree(999, read(input), read(input));
}
// more code here
}
This is the right idea, but C++ and C don't guarantee the order in which arguments to a function are evaulated. THis means the two recursive calls might Not be evaluated in left/right order.
Instead you must write code like this:
Tree * read(ibstream& input)
{
int val;
input.readbits(1,val);
if (val == 0) { // internal node
Tree * left = read(input);
Tree * right = read(input);
return new Tree(999, left,right);
}
The C/C++ system call unlink will remove a file specified by a string as an argument:
To use unlink you need
To write characters/8-bit chunks when unhuffing, use an obstream and writebits:
The Unix command diff tells if two files are the same:
If you compress then uncompress an executable, it will be the same file if you do things correctly, but you won't be able to execute it since it won't have its execute permission set. To do this run the chmod command:
You must create a node, with count/weight 1, that contains PSEUDO_EOF (see globals.h) as the info field of the node, and add this node to the collection of nodes used to make the Huffman tree. You create this node explicitly, it's not created automatically from your counts.
Once created, it will become part of the tree and thus have a zero/one encoding derived from the root-to-leaf path.
You must write this encoding after compressing all the "real" characters (when you re-read the file being compressed). You must write the encoding explicitly.
Your unhuff program will know what the encoding of PSEUDO_EOF is -- see the assignment write-up for how to use the pseudo-eof value when uncompressing.
You can "see" the raw data in a file using the od command (octal dump). One version of use is:
If you use the bitwise and operator & to determine if a bit is on, be sure to parenthesize:
Note that writing the following will NOT work:
If you use a tpqueue (in tpq.h) you may need to declare a comparer object. For an example see tpqtest.cpp. Note the use of the typedef in that code for Thing *, the alias Thingptr is used. If you DON'T use this, you'll probably make a mistake in your compare function. It should have this prototype:
In particular, look where the const is, NOT before Thing, hence the typedef alias to make things easier.
It's a little tricky to declare a priority queue in the private section of a class if you're going to construct it from a a comparer object (like the code in tpqtest.cpp and pqdemo.cpp.)
Most likely, you'll use the priority queue in some member function that creates a tree. So you can declare the pq in that function, with the comparer class in the .cpp file for the class. Supose you have a class HuffTree
If you really need to declare the priority queue as a private data member you might want to look at the implementation of tpqueue in tpq.h and tpq.cpp to see how the static comparer object is created and used.
Alternatively, you can define a Comparer object in your .cpp file, NOT inside a class, but global to the file: