New to file input/output, dont know where im going wrong.

Doing an assignment that merges two text files and i cant figure out why no text is being outputted to my merge file. Please give me a hint/pointer to what im doing wrong.

Here is the pseudocode as well
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
// Start
//     Declarations
//         InputFile inFile1;
//         InputFile inFile2;
//         OutputFile outFile1;
//         num mClientNumber, fClientNumber
//         string mClientName, fClientName
//         bool atLeastOneFileNotAtEnd = true
//         bool inFile1Written = false
//         bool inFile2Written = false
//     output "File merge processing starting"
//     open inFile1 "MaleClients.rtf"
//     open inFile2 "FemaleClients.rtf"
//     open outFile1 "MergedClients.rtf"
//     read mClientNumber and mClientName from inFile1
//     read fClientNumber and fClientName from inFile2
//     while ( atLeastOneFileNotAtEnd == true )
//       if (inFile1 is EOF)
//         if (inFile2Written == false)
//           output fClientNumber, fClientName to Outputfile
//           inFile2Written = true
//         endif
//       else if (inFile2 is EOF)
//         if (inFile1Written == false)
//           output mClientNumber, mClientName to Outputfile
//           inFile1Written = true
//         endif
//       else if (mClientNumber < fClientNumber)
//         output mClientNumber, mClientName to Outputfile
//         inFile1Written = true
//       else
//         output fClientNumber, fClientName to Outputfile
//         inFile2Written = true
//       endif
//
//
//       if ((inFile1 not EOF) AND (inFile1Written == true))
//         read mClientNumber and mClientName from inFile1
//         inFile1Written = false
//       endif
//       if ((inFile2 not EOF) AND (inFile2Written == true))
//         read fClientNumber and fClientName from inFile2
//         inFile2Written = false
//       endif
//       if ((inFile is EOF) AND (inFile2 is EOF))
//         atLeastOneFileNotAtEnd = false
//       endif
//     endwhile
//     close inFile1
//     close inFile2
//     close outFile1
//     output "Merging Complete"
// Stop



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
77
#include <iostream>
#include <fstream>
using namespace std;

int main ()
{
	ifstream infile1("FemaleClients.rtf");
	ifstream infile2("MaleClients.rtf");
	ofstream outfile1("MergedClients.rtf");
	int mClientNumber;
	int fClientNumber;
	string mClientName;
	string fClientName;
	bool atLeastOneFileNotAtEnd = true;
	bool inFile1Written = false;
	bool inFile2Written = false;
	infile1 >> mClientNumber >> mClientName;
	infile2 >> fClientNumber >> fClientName;
	
	cout << "File merge processing starting...";
	
	while (atLeastOneFileNotAtEnd == true)
	{
		if (infile1.eof())
		{
			if (inFile2Written == false)
			{
				outfile1 << fClientNumber << fClientName;
				inFile2Written = true;
			}
		else if (infile2.eof()){
		
			if (inFile1Written == false)
			{
			outfile1 << mClientNumber << mClientName;
			inFile1Written = true;
			}
		}
		else if (mClientNumber < fClientNumber)
			{
			outfile1 << mClientNumber << mClientName;
			inFile1Written = true;
		}
		else {
			outfile1 << fClientNumber << fClientName;
			inFile2Written = true;
		}
		}
		
		if((!infile1.eof()) and (inFile1Written == true))
		{
			infile1 >> mClientNumber >> mClientName;
			inFile1Written = false;
		}
		if((!infile2.eof()) and (inFile2Written == true))
		{
			infile2 >> fClientNumber >> fClientName;
			inFile2Written = false;
		}
		
		if((infile1.eof()) and (infile2.eof()))
		{
			atLeastOneFileNotAtEnd = false;	
		}
		
	}
	
	infile1.close();
	infile2.close();
	outfile1.close();
	cout << "Merging Completed!!!!!";
	


	return 0;	
}
  
Last edited on
First you should be checking if the files all opened correctly before your loop.

Next you probably should read from the input files before you try to write to the output file.

When merging the input files can you read one file at a time writing the information as you go?

Note that ifstream::eof() only checks the eofbit, i.e. it tells you whether a previous read operation has failed because of hitting the end of the file. But other errors are possible! In which case the failbit or badbit will be set instead of the eofbit. So, it's probably better to check ifstream::good() instead of ifstream::eof(), because ifstream::good() will only return true, if neither the eofbit, failbit or badbit are set.

https://www.cplusplus.com/reference/ios/ios/good/

Also note that it is not sufficient to check ifstream::good() (or ifstream::eof()) before calling operator>>(). That is because even if there was no error until now, the next read operation may fail! So it's necessary to check the error bits after each read operation in order to determine whether the read has succeeded.


This expression:
if ((!infile1.eof()) and (inFile1Written == true))
...can be simplified to just:
if ((!infile1.eof()) && inFile1Written)

And the expression:
if (inFile1Written == false)
...can be simplified to just:
if (!inFile1Written)
Last edited on
It's easier to write the merge in two loops. The first for when neither file is eof, then another loop to finish off the unfinished file.

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
#include <iostream>
#include <fstream>
using namespace std;

int main() {
    ifstream in_f("FemaleClients.txt");
    if (!in_f) {
        cerr << "Cannot open FemaleClients.txt\n";
        return 1;
    }

    ifstream in_m("MaleClients.txt");
    if (!in_m) {
        cerr << "Cannot open MaleClients.txt\n";
        return 1;
    }

    ofstream out("MergedClients.txt");
    if (!out) {
        cerr << "Cannot open MergedClients.txt\n";
        return 1;
    }

    int mNum, fNum;
    string mName, fName;
    auto output = [&out](int num, const string& name)
                        { out << num << ' ' << name << '\n'; };

    in_f >> fNum >> fName;
    in_m >> mNum >> mName;

    while (in_f && in_m)
        if (mNum < fNum) { output(mNum, mName); in_m >> mNum >> mName; }
        else             { output(fNum, fName); in_f >> fNum >> fName; }

    if      (in_f) do output(fNum, fName); while (in_f >> fNum >> fName);
    else if (in_m) do output(mNum, mName); while (in_m >> mNum >> mName);
}


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
FemaleClients.txt
2  a
4  b
7  c
8  d
11 e
15 f

MaleClients.txt
3  A
5  B
9  C
12 D
13 E

MergedClients.txt
2 a
3 A
4 b
5 B
7 c
8 d
9 C
11 e
12 D
13 E
15 f

Last edited on
Topic archived. No new replies allowed.