Merging Two Files using C++

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • ckoniecny@gmail.com

    Merging Two Files using C++

    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("Fil e1.txt", ios::in);
    File2.open("Fil e2.txt", ios::in);

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



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

    File2 >File2_num >File2_FirstNam e >File2_LastName ;
    while (!File1.eof())
    {
    File1 >File1_num >File1_FirstNam e >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?

  • Jerry Coffin

    #2
    Re: Merging Two Files using C++

    In article <1158983152.137 269.277520@m7g2 000cwm.googlegr oups.com>,
    ckoniecny@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_FirstNam e >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_it erator 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<(recor d const &other) const {
    return number < other.number;
    }
    };


    // ...
    std::merge(
    std::istream_it erator<record>( infile1),
    std::istream_it erator<record>( ),
    std::istream_it erator<record>( infile2),
    std::istream_it erator<record>( ),
    std::ostream_it erator<record>( outfile, "\n"));

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.

    Comment

    • ckoniecny@gmail.com

      #3
      Re: Merging Two Files using C++

      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 <1158983152.137 269.277520@m7g2 000cwm.googlegr oups.com>,
      ckoniecny@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_FirstNam e >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_it erator 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<(recor d const &other) const {
      return number < other.number;
      }
      };
      >
      >
      // ...
      std::merge(
      std::istream_it erator<record>( infile1),
      std::istream_it erator<record>( ),
      std::istream_it erator<record>( infile2),
      std::istream_it erator<record>( ),
      std::ostream_it erator<record>( outfile, "\n"));
      >
      --
      Later,
      Jerry.
      >
      The universe is a figment of its own imagination.

      Comment

      • Jerry Coffin

        #4
        Re: Merging Two Files using C++

        In article <1158986868.602 108.203100@b28g 2000cwb.googleg roups.com>,
        ckoniecny@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.

        Comment

        • ckoniecny@gmail.com

          #5
          Re: Merging Two Files using C++

          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("fil e1", ios::in);
          File2.open("fil e2", ios::in);
          outFile.open("o ut.txt", ios::out);

          File1 >File1_acctNu m >File1_fName >File1_lName;
          File2 >File2_acctNu m >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_acctNu m >File1_fName >>
          File1_lName;
          File2 >File2_acctNu m >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.eo f())
          {
          outFile << File1_acctNum << '\t' <<
          File1_fName << '\t'
          << File1_lName << '\n';
          }
          }

          }
          return 0;
          }

          Comment

          • Jerry Coffin

            #6
            Re: Merging Two Files using C++

            In article <1159073798.586 505.60510@m7g20 00cwm.googlegro ups.com>,
            ckoniecny@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.

            Comment

            Working...