Sign in to follow this  
toogreat4u

Reading two files in and creating one output file

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this