944,038 Members | Top Members by Rank

Ad:
  • C++ Discussion Thread
  • Unsolved
  • Views: 7811
  • C++ RSS
Sep 13th, 2007
0

Merge Two Files

Expand Post »
So i have an assignment to take two input files and combine into one output file in alphabetical order.

Example

File1.txt
Adam B Exam 80
Jane D Exam 87
Tom G Exam 77

File2.txt
George S Exam 99
Bob C Exam 67

Output.txt
Adam B
Bob C
George S
Jane D
Tom G

I have tried for hours to get this to work i think i might be on the correct path.

C++ Syntax (Toggle Plain Text)
  1. #include <iostream>
  2. #include <fstream>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. int openFiles (string inFile1, string inFile2, string outFile1);
  8. void mergeFiles (string inFile1, string inFile2, string outFile1,ifstream& File1,ifstream& File2,ofstream& outFile);
  9.  
  10.  
  11. int main()
  12. {
  13. string inFile1, inFile2, outFile1;
  14. ifstream File1;
  15. ifstream File2;
  16. ofstream outFile;
  17.  
  18. cout <<"Enter input file 1:"<<endl;
  19. cin >>inFile1;
  20. cout <<"Enter input file 2:"<<endl;
  21. cin >>inFile2;
  22. cout <<"Enter output file 1:"<<endl;
  23. cin >>outFile1;
  24.  
  25. openFiles (inFile1, inFile2, outFile1);
  26. mergeFiles (inFile1, inFile2, outFile1, File1, File2, outFile);
  27.  
  28.  
  29. return 0;
  30.  
  31. }
  32.  
  33. void mergeFiles (string inFile1, string inFile2, string outFile1,ifstream& File1,ifstream& File2,ofstream& outFile)
  34. {
  35. File1.open(inFile1.c_str());
  36. File2.open(inFile2.c_str());
  37. outFile.open(outFile1.c_str());
  38.  
  39. string File1_fName, File1_lName,exam1,examGrade1;
  40. string File2_fName, File2_lName,exam2,examGrade2;
  41.  
  42.  
  43.  
  44. File1 >> File1_fName >> File1_lName>>exam1>>examGrade1;
  45. File2 >> File2_fName >> File2_lName>>exam2>>examGrade2;
  46.  
  47. while (!File1.eof() && !File2.eof())
  48. {
  49.  
  50. if ((File1_fName<=File2_fName ))
  51. {
  52. outFile << File1_fName << '\t'<< File1_lName << endl;
  53. File1 >> File1_fName >> File1_lName>>exam1>>examGrade1;
  54.  
  55. }
  56. else
  57. {
  58. outFile << File2_fName << '\t'<< File2_lName << endl;
  59. File2 >> File2_fName >> File2_lName>>exam2>>examGrade2;
  60. }
  61. if (File1.eof() )
  62. {
  63. while (!File2.eof())
  64. {
  65. outFile << File2_fName << '\t'<< File2_lName << endl;
  66. }
  67. }
  68.  
  69.  
  70. if (File2.eof() )
  71. {
  72. while (!File1.eof())
  73. {
  74. outFile << File1_fName << '\t'<< File1_lName << endl;
  75. }
  76. }
  77.  
  78.  
  79.  
  80. File1.close();
  81. File2.close();
  82. outFile.close();
  83. }
  84.  
  85. }
  86.  
  87.  
  88.  
  89. int openFiles (string inFile1, string inFile2, string outFile1)
  90. {
  91. ofstream outFile;
  92. outFile.open (outFile1.c_str());
  93.  
  94. if (outFile.fail())
  95. {
  96. cerr << "ERROR: cannot open " <<outFile1
  97. << " for output." <<endl;
  98. return EXIT_FAILURE;
  99. }
  100.  
  101.  
  102. ifstream File1;
  103. File1.open (inFile1.c_str());
  104.  
  105. if (File1.fail())
  106. {
  107. cerr << "ERROR: cannot open " <<inFile1
  108. << " for input." <<endl;
  109. return EXIT_FAILURE;
  110.  
  111. }
  112.  
  113. ifstream File2;
  114. File2.open (inFile2.c_str());
  115.  
  116. if (File2.fail())
  117. {
  118. cerr << "ERROR: cannot open " <<inFile2
  119. << " for input." <<endl;
  120. return EXIT_FAILURE;
  121. }
  122. }
Similar Threads
Reputation Points: 10
Solved Threads: 0
Newbie Poster
cspivey is offline Offline
2 posts
since Sep 2007
Sep 13th, 2007
0

Re: Merge Two Files

you need to put the information in the input files into one vector, then sort the vector, and finally write the vector contents to the output file. From the example files you posted this will be fairly simple. You can use std::sort to sort the vector after reading from the input files.

Also, do not use eof() because they don't work the way you would expect.
C++ Syntax (Toggle Plain Text)
  1. vector<string> theList;
  2. string line;
  3. while( getline(File1, line )
  4. {
  5. theList.push_back(line));
  6. }
  7. while( getline(File2, line) )
  8. {
  9. theList.push_back(line));
  10. }
  11. // sort the vector
  12. sort(theList.begin(),theList.end());
  13. // now write the vector out the the output file
Last edited by Ancient Dragon; Sep 13th, 2007 at 10:08 pm.
Sponsor
Team Colleague
Featured Poster
Reputation Points: 5608
Solved Threads: 2282
Retired and Enjoying Life
Ancient Dragon is online now Online
21,954 posts
since Aug 2005
Sep 13th, 2007
0

Re: Merge Two Files

We have not covered vectors on the class that i am in right now... my instructor said that we should use the getline or the way that i was doing it...if anyone could show me how to retrieve the data using getline i might can change up what i have...or why the way i currently have it is not working...thanks
Reputation Points: 10
Solved Threads: 0
Newbie Poster
cspivey is offline Offline
2 posts
since Sep 2007
Sep 14th, 2007
0

Re: Merge Two Files

The algorithm you was using may or may not work, depending on the contents of the two input files. It might work if both input files are already in sorted order. If the lines are scrambled in each file then your algorithm can not and will not work. The only way to do it correctly is to read both files into a single array, whether vectors or c-style character arrays, then sort them and write to the final output file

do you know about c-style character arrays of pointers yet ? You can substitute vector for an array of c-strings then sort the strings using some algorithm such as qsort() or a bubble sort (there are lots of other sort options too).
Sponsor
Team Colleague
Featured Poster
Reputation Points: 5608
Solved Threads: 2282
Retired and Enjoying Life
Ancient Dragon is online now Online
21,954 posts
since Aug 2005
Sep 14th, 2007
0

Re: Merge Two Files

If this is an exercise in "merge", then shouldn't all the input files be sorted already ?
Team Colleague
Reputation Points: 5862
Solved Threads: 950
Posting Sage
Salem is offline Offline
7,164 posts
since Dec 2005
Sep 14th, 2007
0

Re: Merge Two Files

Try this :
C++ Syntax (Toggle Plain Text)
  1. #include<iostream>
  2. #include<string>
  3. #include<fstream>
  4. using namespace std;
  5.  
  6. int main()
  7. {
  8. int ndatamax=100;
  9. string line[ndatamax],linetemp;
  10. int i=0;
  11. int ndata;
  12. ifstream myfile;
  13. myfile.open("data.txt");
  14.  
  15. if(myfile.is_open())
  16. {
  17. while(!myfile.eof())
  18. {
  19. getline(myfile,line[i]);
  20. i++;
  21.  
  22. }
  23. }
  24. ndata=i-1;
  25. // One way for sorting
  26. for(i=0;i<ndata;i++)
  27. {
  28. for(int j=i+1;j<ndata;j++)
  29.  
  30. if( line[i]>line[j]) { linetemp=line[i]; line[i]=line[j];line[j]=linetemp;}
  31. }
  32.  
  33.  
  34. // new sequence
  35. for(i=0;i<ndata;i++)
  36. {
  37. cout<<line[i]<<endl;
  38. }
  39.  
  40.  
  41. }
Last edited by Narue; Sep 14th, 2007 at 10:41 am. Reason: Added code tags
Reputation Points: 8
Solved Threads: 0
Newbie Poster
jusakman is offline Offline
5 posts
since Sep 2007
Sep 14th, 2007
0

Re: Merge Two Files

>int ndatamax=100;
>string line[ndatamax]
C++ requires array sizes to be constant.

>while(!myfile.eof())
*sigh* It seems we have to tell everyone that this is the wrong way to use the eof member function. The eofbit is only set after an attempt has been made to read from the stream and failed. This means that the body of your loop will execute once more than expected. For example:
C++ Syntax (Toggle Plain Text)
  1. #include <cstddef>
  2. #include <fstream>
  3. #include <iostream>
  4. #include <string>
  5.  
  6. void create_file ( const char *filename, const char *contents )
  7. {
  8. std::ofstream out ( filename );
  9.  
  10. if ( out )
  11. out<< contents;
  12. }
  13.  
  14. int main()
  15. {
  16. const char *filename = "test.txt";
  17.  
  18. create_file ( filename, "Line1\nLine2\nLine3\n" );
  19.  
  20. {
  21. std::ifstream in ( filename );
  22. std::string line;
  23. std::size_t n = 0;
  24.  
  25. if ( in ) {
  26. while ( !in.eof() ) {
  27. std::getline ( in, line );
  28. ++n;
  29. }
  30.  
  31. std::cout<<"The file has "<< n <<" lines\n";
  32. }
  33. }
  34.  
  35. {
  36. std::ifstream in ( filename );
  37. std::string line;
  38. std::size_t n = 0;
  39.  
  40. if ( in ) {
  41. while ( std::getline ( in, line ) )
  42. ++n;
  43.  
  44. std::cout<<"The file has "<< n <<" lines\n";
  45. }
  46. }
  47. }
Even worse, the content of the file will affect the result of the broken loop. If you change "Line1\nLine2\nLine3\n" to "Line1\nLine2\nLine3", the first loop will result in 3 instead of 4, but the second loop will still produce 3. The rule of thumb is that the eof member function (or feof in C) should never be used to drive an input loop. It's just too easy to screw up.

>ndata=i-1;
With your broken loop, this becomes an intermittent bug.

>for(int j=i+1;j<ndata;j++)
>if( line[i]>line[j]) { linetemp=line[i]; line[i]=line[j];line[j]=linetemp;}
Just for future reference, I think this formatting is evil. First, multi-line blocks should never be scrunched up onto a single line. Second, whitespace is your friend, so the conditional should look like this:
C++ Syntax (Toggle Plain Text)
  1. if ( line[i] > line[j] ) {
  2. linetemp = line[i];
  3. line[i] = line[j];
  4. line[j] = linetemp;
  5. }
Next, when you format the conditional in an easier to maintain fashion, the seemingly one line loop suddenly has five lines in the body:
C++ Syntax (Toggle Plain Text)
  1. for ( int j = i + 1; j < ndata; j++ )
  2. if ( line[i] > line[j] ) {
  3. linetemp = line[i];
  4. line[i] = line[j];
  5. line[j] = linetemp;
  6. }
Just because a compound statement counts as a single statement doesn't mean that omitting braces for this loop is a good idea. In fact, not using braces is a pretty bad idea in general except when you have a very trivial single line body. That way it's immediately obvious that braces need to be added with more lines. This is much better:
C++ Syntax (Toggle Plain Text)
  1. for ( int j = i + 1; j < ndata; j++ ) {
  2. if ( line[i] > line[j] ) {
  3. linetemp = line[i];
  4. line[i] = line[j];
  5. line[j] = linetemp;
  6. }
  7. }
In fact, a good guideline to follow is that every block has braces.
Administrator
Reputation Points: 6442
Solved Threads: 1393
Bad Cop
Narue is offline Offline
11,807 posts
since Sep 2004
Sep 14th, 2007
0

Re: Merge Two Files

Thanks NArue.. I never realized that thing before.
Reputation Points: 8
Solved Threads: 0
Newbie Poster
jusakman is offline Offline
5 posts
since Sep 2007

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C++ Forum Timeline: Socket issue + LAN
Next Thread in C++ Forum Timeline: Simple Binary Crypt





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC