Merge two input texts

Hello, this program is to merge and alphabetize two input text files and output them. (assuming files are already alphabetized) The example used is:
(input 1)
Adams C
Jones D
King B

(input 2)
Barnes A
Johnson C

The output only displays the first two and does not continue to the next line of string of data. Only this is displayed:
Adams c
Barnes A

How would I fix this? Thanks.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
  /*
 */

#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;

#define inFile1 "input1"
#define inFile2 "input2"
#define outFile "output"

void mergeInputs (ifstream&, ifstream&, ofstream&);

int main()
{
    ifstream in1,
            in2;
    ofstream out;
    
    in1.open(inFile1);
    if (in1.fail())
    {
        cerr << "*** ERROR: Cannot open " << inFile1 << " for input." << endl;
        return EXIT_FAILURE;
    }
    
    in2.open(inFile2);
    if (in2.fail())
    {
        cerr << "*** ERROR: Cannot open " << inFile2 << " for input." << endl;
        return EXIT_FAILURE;
    }
    
    out.open(outFile);
    if (out.fail())
    {
        cerr << "*** ERROR: Cannot open " << outFile << " for input." << endl;
        return EXIT_FAILURE;
    }
    
    mergeInputs(in1, in2, out);
    
    in1.close();
    in2.close();
    out.close();
    
    return 0;
}

void mergeInputs (ifstream& in1, ifstream& in2, ofstream& out)
{
    string str1,
             str2;
    
    getline(in1, str1);
    getline(in2, str2);
    
    while(!in1.eof() && !in2.eof())
    {
        
        if(str1 <= str2)
        {
            out << str1 << endl;
            getline(in1, str1);
        }
        
        else
        {
            out << str2 << endl;
            getline(in2, str2);
        }
    }
    
}
After Barnes A is put into the out file Johnson C is read into str2. At this point in2 has reached the end of the file (all of its values have been read) so the while loop terminates.
After Barnes A is put into the out file Johnson C is read into str2. At this point in2 has reached the end of the file (all of its values have been read) so the while loop terminates.


Shouldn't while(!in1.eof() && !in2.eof()) - the && - require both in1 and in2 before terminating?
No, it requires both to not be at the end to continue doing the loop. If either fails the loop will terminate. It's read "WHILE in1 is not at the end AND in2 is not at the end continue reading" but in2 is at the end, so it doesn't continue reading.
Alright so after a while I came up with this. The problem I was having was that the original while loop did not output Johnson C and so I could not simply output the rest of input 1 after the loop. (or input 2 if the reverse were the case)

I have created another continuation to the function but I know it is not as efficient as possible. Is it possible to keep using the while loop with .eof and include the final line before terminating the loop? (outputting Johnson C) That way I would be able to output the rest of the remaining file lines. Thanks.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
void mergeInputs (ifstream& in1, ifstream& in2, ofstream& out)
{
    string str1,
             str2;
    
    getline(in1, str1);
    getline(in2, str2);
    
    while(!in1.eof() && !in2.eof())
    {
        
        if(str1 < str2)
        {
            out << str1 << endl;
            getline(in1, str1);
        }
        
        else
        {
            out << str2 << endl;
            getline(in2, str2);
        }
    }
    
    if(in2.eof())
    {
        if(str1 < str2)
        {
            out << str1 << endl;
            out << str2 << endl;
            getline(in1, str1);
        }
        else
        {
            out << str2 << endl;
            out << str1 << endl;
            getline(in1, str1);
        }
        while(!in1.eof())
        {
           out << str1 << endl;
           getline(in1, str1);
        }
        out << str1 << endl;
    }
    else
    {
        if(str1 < str2)
        {
            out << str1 << endl;
            out << str2 << endl;
            getline(in2, str2);
        }
        else
        {
            out << str2 << endl;
            out << str1 << endl;
            getline(in2, str2);
        }
        while(!in2.eof())
        {
           out << str2 << endl;
           getline(in2, str2);
        }
        out << str2 << endl;
    }
    
}
Sadly, still have yet to find a way to include the last line in the original while loop, if anyone is able to help!
For exposition, assume that input file 1 has more data than input file 2.

After line 24, you assume that there are still comparisons to be made. By line 24, str2 has already been used and in2 is at EOF.

That leaves a valid str1 and whatever lies after it in input file 1.


Hope this helps.
Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <string>
using namespace std;

void mergeInputs (istream& in1, istream& in2, ostream& out)
{	string str1,
           str2;

    getline (in1, str1);
	getline (in2, str2);

    while (in1 || in2)
    {	//	We want to continue until we have eof on both files        
        if (in1 && in2 && str1 < str2)
        {	//	Both strings are valid
			out << str1 << endl;
            getline(in1, str1);
			continue;	// go to next iteration of loop
        }
        if(in1 && in2 && str1 > str2)
        {	//	Both strings are valid
			out << str2 << endl;
            getline(in2, str2);
			eof2 = in2.eof();
			continue;	// go to next iteration of loop
        }
		if(in1 && in2 && str1 == str2)
        {	//	Both strings are valid and equal
			out << str2 << endl;
			//	Read from both files
			getline(in1, str1);
			getline(in2, str2);
			continue;	// go to next iteration of loop
        }
		if (in1)
		{	//	Write str1 (in2 is at eof)
			out << str1 << endl;
			getline(in1, str1);
			continue;	// go to next iteration of loop
		}		
		if (in2)
		{	// write str2 (in1 is at eof)
			out << str2 << endl;
            getline(in2, str2);
			continue;	// go to next iteration of loop 
		}
	}
} 

Last edited on
Thanks!
Topic archived. No new replies allowed.