I encode a text file using a huffman tree. Which print out to the screen and and output to a file. File only contains the last line that prints to the console.

void traverse(string code = "") const {
		string outputFile = "huffman.txt";
		ofstream outfile(outputFile.c_str());


		if (child0 !=NULL) {

			static_cast<huffman_item<dtype> >( *child0).traverse(code + '0' );		

			static_cast<huffman_item<dtype> >( *child1).traverse(code + '1' );

		} else{

			outfile << data << freq << code << endl;
			cout << " Data: " << data << " Frequency: " << freq << " Code: " << code << endl;

		}

	}

This is method. Can someone please help me!

Dani AI

Generated

The symptom (only the last line ends up in the file) is caused by opening the output file inside the recursive routine: every call constructs a fresh ofstream with the default truncation mode, so earlier writes get wiped. Also the original calls using static_cast<...>(*child0).traverse(...) are risky — that casts to a temporary value (object slicing) and calls traverse on the copy instead of the actual child. Fix both by keeping the stream open once and invoking recursion on the actual node objects.

Example — open the file once and pass an output stream reference into the recursive method:

std::ofstream fout("huffman.txt");
root->traverse("", fout);

void traverse(const std::string& prefix, std::ostream& out) const {
    if (child0 && child1) {
        child0->traverse(prefix + '0', out);
        child1->traverse(prefix + '1', out);
        return;
    }
    out << data << ' ' << freq << ' ' << prefix << '\n';
}

Alternate pattern: build the code table first into a container, then write the container once after traversal. That separates traversal logic from I/O and makes testing easier:

std::unordered_map<dtype,std::string> codes;
root->buildCodes(codes,"");
/* then write codes to file once */

Practical tips: check fout.is_open() before writing; prefer '\n' over std::endl unless you need an immediate flush; avoid static_cast on dereferenced pointers — use child->traverse(...) to prevent slicing; and ensure your leaf test is correct (both children null for a leaf). As and were circling, moving file creation out of the recursive body and fixing the call form will resolve the overwrite/last-line-only behavior.

Recommended Answers

All 6 Replies

Is recursion really necessary for this? Whenever possible avoid using it. It's inefficient, hard to implement, and hard to debug. It seems as though the function recursively calls itself until it is at the end of the list, then it displays a line. In each recursive call, you should be outputting a line, otherwise it will traverse to the end and display the last line. If recursion isn't necessary, use a loop instead.

figure out the problem! this is a recursive function...

figure out the problem! this is a recursive function...

Ummm...ok? I'm pretty sure I told you the solution. Being polite will get you farther in life.

yeah it creates a output file each time the function is called. the way i have it setup i need a recursive function.

I replied the before I read you solution. Didn't expect a quick response. Sorry mate!

I still have the same problem though! Need to figure out a way to edit an existing file rather than create a new file. Or maybe I should create a file before the function is called...

Open the file in append mode.

ostream fOut;
fOut.open("file.dat", ios::append);

I'm pretty sure that's how it's done.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.