Reading two files in and creating one output file

Started by
1 comment, last by Zahlman 14 years, 10 months ago
Here is the problems statement:
Quote: Write a program that merges the numbers in two files and writes all the numbers into a third file. Your program takes input from two different files and writes its output to a third file. Each input file contains a list of numbers of type int in sorted order from the smallest to the largest. After the program is run, the output fie will contain all the numbers in the two input files in one longer list in sorted order from smallest to largest. Your program should define a function that is called with two input-file streams and the output-file stream as three arguments.
I am doing this as an exercises on my own from a C++ book to refresh my memory on how some things work in C++. Anyhow consider the fact that up to this point (in the text I am reading) there has been no mention of array's or sorting algorithms yet. So my problem is for some reason I am having a severe brain cramp and can't figure out how to read these two files in correctly. So far I know the function will be as follows:

void merge(ifstream& in, ifstream& in2, ofstream& out)
{
	// type of values being read in from file 1
	int num;
	// type of values being read in from file 2
	int num2;

        /* tried while(in >> num || in2 >> num2)
         * then if(num < num2)
         *         out << num << endl;
         *         in2.putback(num2); 
         *      else
         *         out << num2 << endl;
         *         in.putback(num)
         * this fails most likely because putback places a char value back
         * into the stream but I could be wrong but that example what
         * I am trying to do but failing :)
         */

	return;
}

My basic question is how do I read these files in simultaneously and get the answer I am looking for. Thanks for any help.
Advertisement
You have the right idea of in >> int1; and in2 >> int2;, you have to be careful you're not at the end of the file.

Here's a hint:

With files A and B for input, and C for output, there are four possible states your code can be in:
1) !A.eof() && !B.eof() -- Read from A and B
2) !A.eof() && B.eof() -- Dump the rest of A into C
3) A.eof() && !B.eof() -- Dump the rest of B into C
4) A.eof() && B.eof() -- All done!

EDIT:
Upon closer examination, while(in >> num || in2 >> num2) doesn't do what you think it does. Due to lazy-evaluation, the program will only execute in2 >> num2 only if in >> num is false; you could switch to && instead of || such that both conditions are evaluated, however if one fails, they both fail (in other words, the input will be limited to minimum number of numbers of both files). You can also use a comma, while( in >> num, in2 >> num2 ) -- executes in >> num and tests in2 >> num2, but if there's a dim-mismatch either the last number in in gets repeated, or the last few in in won't be read. The best way would be to handle all four of the possible states listed above.

[Edited by - _fastcall on May 30, 2009 10:27:08 AM]
Quote:Original post by toogreat4u
Anyhow consider the fact that up to this point (in the text I am reading) there has been no mention of arrays


That's fine; you don't need anything like that here.

Quote:or sorting algorithms yet.


That's also fine; the input is already sorted, and your "merge" operation will automatically sort the output.

Quote:So my problem is for some reason I am having a severe brain cramp and can't figure out how to read these two files in correctly.


First, sketch out the algorithm. I want you to try the following:

First, shuffle a deck of cards, and split it into two halves (they don't have to be the same size).

Sort each half of the deck (in whatever way you like) in a consistent order - e.g. clubs 2 through ace, then diamonds, hearts and spades. Set up the two halves in front of you with the cards face up, so that the 2 of clubs is on the top of one of the two decks. (That is, each deck is sorted from "smallest" to "largest", with smallest on top.)

Now, merge the decks, by - at every step - taking the smaller of the two cards on top of the 'input' decks, and putting it face down on top of an 'output' deck. One of the inputs will run out before the other; at that point, you can just start drawing cards one at a time from the other input.

Now, flip over the 'output'. (The thing about putting them face down and then flippin the deck is so that the first card you put in the output ends up on top, just as with a file - the first thing you write to a file is at the beginning of the file.) Notice that it is now completely sorted from smallest to largest.



So, how do we do this in code?

Well, we need to open the two input streams, and check the "top card" of each by reading it into a variable. Then we need to run a loop that takes the smaller of the two "showing" cards, puts it in the output, and "reveals" the next number in the file whose value we took, by reading it. (That "revealing" step is automatic with the actual decks of cards.) If we can't reveal another card, it's because that file is done; so we exit this loop, and enter another one to just copy values from the other file.

This topic is closed to new replies.

Advertisement