By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,601 Members | 989 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,601 IT Pros & Developers. It's quick & easy.

Merging Two Files using C++

P: n/a
I have the following two files:
File1:
11 John Doe
33 Jane Doe
55 Steve Smith

File2:
22 Joe Doe
44 Willy Widget

I'm trying to merge the two files to look like:

Output:
11 John Doe
22 Joe doe
33 Jane Doe
44 Willy Widget
55 Steve Smith

Note: I cannot use array's to sort.

This is the code I have thus far:

Code:
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
ifstream File1, File2;
string File1_FirstName, File1_LastName;
string File2_FirstName, File2_LastName;
int File1_num, File2_num, NumberOne, NumberTwo;
ofstream outFile;

File1.open("File1.txt", ios::in);
File2.open("File2.txt", ios::in);

outFile.open("Output.txt", ios::out);

while (!File2.eof())
{
File1 >File1_num >File1_FirstName >File1_LastName;
NumberOne = File1_num;

File2 >File2_num >File2_FirstName >File2_LastName;
while (!File1.eof())
{
File1 >File1_num >File1_FirstName >File1_LastName;
NumberTwo = File1_num;

if ( NumberOne File2_num < NumberTwo )
{
outFile << NumberOne << '\t'
<< FirstName << '\t'
<< LastName << '\n';
}
}
}
return 0;
}
My output is not what I expected, I'm having logic issues. Can anyone
point me in the correct direction?

Sep 23 '06 #1
Share this Question
Share on Google+
5 Replies


P: n/a
In article <11**********************@m7g2000cwm.googlegroups. com>,
ck*******@gmail.com says...
I have the following two files:
File1:
11 John Doe
33 Jane Doe
55 Steve Smith

File2:
22 Joe Doe
44 Willy Widget

I'm trying to merge the two files to look like:

Output:
11 John Doe
22 Joe doe
33 Jane Doe
44 Willy Widget
55 Steve Smith
I'd define a class that holds the data and defines operator< to sort the
data in the desired fashion (you haven't described what should happen
if, for example, the same number appears with two different names).

From there, you can directly merge from input files to an output file if
the input files are guaranteed to be sorted, as you've shown them here.
Otherwise, you can copy from the input files to a sorted container (e.g.
set or multiset, depending on whether duplicate keys are allowed) and
then merge from there to the output.

I'm not sure why can _can't_ use arrays (as you mentioned in a snipped
portion of your post) but I'd certainly consider it ill-advised.

As far as the code you have goes, something like this:
while (!File2.eof())
{
File1 >File1_num >File1_FirstName >File1_LastName;

is essentially certain to be incorrect, and normally needs to be
rewritten to something like:

while (file1>>input1>>input2>>input3>>inputN)
// whatever

The important point is that you need to check for a problem with reading
the input file AS you read it -- file.eof() only becomes true AFTER
you've reached the end of the file, so your loop attempts to read the
last data in the file twice. I'd forget about using explicit loops,
however, and just use an std::istream_iterator to read the input.

Your code also has a problem in that each iteration through the loop
reads input from each file, but only writes an output from one file --
and discards the input it read from the other file. Each iteration
should read only ONE input, to replace the one just written out.

As previously noted, however, I'd use std::merge() for this job -- it's
written specifically for tasks like this, and does them quite nicely.

class record {
int number;
std::string first_name, last_name;
public:
friend
std::istream &operator>>(std::istream &in, record &r) {
return in >r.number >r.first_name >r.last_name;
}

friend std::ostream &operator<<(std::ostream &os, record const &r) {
return os << r.number << "\t"
<< r.first_name << "\t"
<< r.last_name;
}

bool operator<(record const &other) const {
return number < other.number;
}
};
// ...
std::merge(
std::istream_iterator<record>(infile1),
std::istream_iterator<record>(),
std::istream_iterator<record>(infile2),
std::istream_iterator<record>(),
std::ostream_iterator<record>(outfile, "\n"));

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 23 '06 #2

P: n/a
Thats a little bit above my level. Is there anyway I can email you
what I have so you can see my actual program?

Jerry Coffin wrote:
In article <11**********************@m7g2000cwm.googlegroups. com>,
ck*******@gmail.com says...
I have the following two files:
File1:
11 John Doe
33 Jane Doe
55 Steve Smith

File2:
22 Joe Doe
44 Willy Widget

I'm trying to merge the two files to look like:

Output:
11 John Doe
22 Joe doe
33 Jane Doe
44 Willy Widget
55 Steve Smith

I'd define a class that holds the data and defines operator< to sort the
data in the desired fashion (you haven't described what should happen
if, for example, the same number appears with two different names).

From there, you can directly merge from input files to an output file if
the input files are guaranteed to be sorted, as you've shown them here.
Otherwise, you can copy from the input files to a sorted container (e.g.
set or multiset, depending on whether duplicate keys are allowed) and
then merge from there to the output.

I'm not sure why can _can't_ use arrays (as you mentioned in a snipped
portion of your post) but I'd certainly consider it ill-advised.

As far as the code you have goes, something like this:
while (!File2.eof())
{
File1 >File1_num >File1_FirstName >File1_LastName;

is essentially certain to be incorrect, and normally needs to be
rewritten to something like:

while (file1>>input1>>input2>>input3>>inputN)
// whatever

The important point is that you need to check for a problem with reading
the input file AS you read it -- file.eof() only becomes true AFTER
you've reached the end of the file, so your loop attempts to read the
last data in the file twice. I'd forget about using explicit loops,
however, and just use an std::istream_iterator to read the input.

Your code also has a problem in that each iteration through the loop
reads input from each file, but only writes an output from one file --
and discards the input it read from the other file. Each iteration
should read only ONE input, to replace the one just written out.

As previously noted, however, I'd use std::merge() for this job -- it's
written specifically for tasks like this, and does them quite nicely.

class record {
int number;
std::string first_name, last_name;
public:
friend
std::istream &operator>>(std::istream &in, record &r) {
return in >r.number >r.first_name >r.last_name;
}

friend std::ostream &operator<<(std::ostream &os, record const &r) {
return os << r.number << "\t"
<< r.first_name << "\t"
<< r.last_name;
}

bool operator<(record const &other) const {
return number < other.number;
}
};
// ...
std::merge(
std::istream_iterator<record>(infile1),
std::istream_iterator<record>(),
std::istream_iterator<record>(infile2),
std::istream_iterator<record>(),
std::ostream_iterator<record>(outfile, "\n"));

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 23 '06 #3

P: n/a
In article <11**********************@b28g2000cwb.googlegroups .com>,
ck*******@gmail.com says...
Thats a little bit above my level. Is there anyway I can email you
what I have so you can see my actual program?
I do have email of course, but if you want help, it's generally better
to post here. That way 1) other people can chip in, and 2) other people
can learn from the discussion.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 23 '06 #4

P: n/a
This is what I have so far and its still not working.... Any hints?

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
ifstream File1;
ifstream File2;
ofstream outFile;

string File1_fName, File1_lName;
string File2_fName, File2_lName;
int File1_acctNum, File2_acctNum;

File1.open("file1", ios::in);
File2.open("file2", ios::in);
outFile.open("out.txt", ios::out);

File1 >File1_acctNum >File1_fName >File1_lName;
File2 >File2_acctNum >File2_fName >File2_lName;
while (!File1.eof() && !File2.eof())
{
if (File2_acctNum File1_acctNum)
{
outFile << File1_acctNum << '\t' << File1_fName
<< '\t'
<< File1_lName << " *\n";
outFile << File2_acctNum << '\t' << File2_fName
<< '\t'
<< File2_lName << " *\n";
File1 >File1_acctNum >File1_fName >>
File1_lName;
File2 >File2_acctNum >File2_fName >>
File2_lName;
cout << File2_acctNum << "\t" << File2_fName <<
"\t" << File2_lName << endl;
}
else if (File1.eof())
{
while (!File2.eof())
{
outFile << File2_acctNum << '\t' <<
File2_fName << '\t'
<< File2_lName << '\n';
}
}
else if (File2.eof())
{
while(!File1.eof())
{
outFile << File1_acctNum << '\t' <<
File1_fName << '\t'
<< File1_lName << '\n';
}
}

}
return 0;
}

Sep 24 '06 #5

P: n/a
In article <11*********************@m7g2000cwm.googlegroups.c om>,
ck*******@gmail.com says...
This is what I have so far and its still not working.... Any hints?
Not any new ones, really.
while (!File1.eof() && !File2.eof())
As already noted, code like this is almost always wrong. You want to
check for EOF _as_ you read the data.

I'd also split things up into a couple of functions, such as
"copy_remainder" (or something like that) to copy the remainder of a
file to the output.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Sep 24 '06 #6

This discussion thread is closed

Replies have been disabled for this discussion.