Loop end unintentionally

.Write a program that merges the numbers in two files and writes all the numbers into a
third file. Your program takes input from two different files and writes its output to a third
file. Each input file contains a list of numbers of type int in sorted order from the smallest
to the largest. After the program is run, the output file will contain all the numbers in the
two input files in one longer list in sorted order from smallest to largest. Your program
should define a function that is called with the two input-file streams and the output-file
stream as three arguments.


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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <string>

using std::exit;
using std::cin;
using std::cout;
using std::ostream;
using std::istream;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::pow;
using std::sqrt;
using std::getline;
using std::string;

const void mergeFile(ifstream& fs1,ifstream& fs2,ofstream& fs3);
//Pre : fs1 & fs2 must exist,fs3 optional
//Post : merge from fs1 and fs2 to fs3,then sort


int main()
{
	ifstream fin1,fin2,fin3;
	ofstream fout;

	cout << "AdviceFromFile - By Kudy" << endl;

	fin1.open("intnum1.txt");
	fin2.open("intnum2.txt");
	fout.open("intnum3.txt");

	if(fin1.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin2.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fout.fail())
	{
		cout << "Fout.Fail()";
		exit(1);
	}

	mergeFile(fin1,fin2,fout);

	fin1.close();
	fin2.close();
	fout.close();
//Actually end before this point,but need a print-to-screen version :
	fin1.open("intnum1.txt");
	fin2.open("intnum2.txt");
	fin3.open("intnum3.txt");

	if(fin1.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin2.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin3.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}
	cout << "intnum1 : " << endl;
	int next;
	while(fin1 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
	cout << "intnum2 : " << endl;
	while(fin2 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
	cout << "intnum3 : " << endl;
	while(fin3 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
//End of print-to-screen part
	return 0;
}

const void mergeFile(ifstream& fs1,ifstream& fs2,ofstream& fs3)
{
	int next1,next2;
	fs1 >> next1;
	fs2 >> next2;
	while((!fs1.eof())||(!fs2.eof())){
		if(next1 < next2)
		{
			fs3 << next1 << " ";
			fs1 >> next1;
		}else{
			fs3 << next2 << " ";
			fs2 >> next2;
		}
	};
}


my lame code,when it take the next input the loop end outta my intention.

plz help...
The while loop in your mergeFile function is looping infinitely. If the last value read from one of your files is smaller than one in the other file, it could cause this to happen.

For instance, lets say in fs1 you have "3 5 7" and in fs2 you have "4 8 12". I'm just gonna go through step by step what your function will do:

1. next1 = 3
next2 = 4

2. Compare 3 < 4, returns true

3. Write 3 to fs3
next1 = 5

4. Compare 5 < 4, returns false

5. Write 4 to fs3
next2 = 8

6. Compare 5 < 8, returns true

7. Write 5 to fs3
next1 = 7

8. Compare 7 < 8, returns true

9. Write 7 to fs3
Attempt to put next value in fs1 into next1. However, there are no values left, so 7 will remain in next1.

10. Compare 7 < 8, returns true

11. Write 7 to fs3
Attempt to put next value in fs1 into next1. However, there are no values left, so 7 will remain in next1.

As you can hopefully see, steps 10 and 11 will now repeat forever. You need to add some way to check if one of your files is at the end.
Actually,when it jumps to the last item in fs1 (or fs2),the loop is stop already,there's no way to use it and compare with items in fs2 (or fs1).the while stop it because it reaches eof.

so some items were lost,and a compiled and the program ends normally => no infinite loop.

Could you check the code again ? I think another marker should do the trick.
Last edited on
I'm not wrong, it's looping infinitely. Your while loop will only terminate when the ends of BOTH files are reached, not just one of them. However, this will never happen due to what I said above. You can add some other checks for one end of file being reached, and if you do it right that should be able to fix it. Just play around with it for a while.
Last edited on
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <string>

using std::exit;
using std::cin;
using std::cout;
using std::ostream;
using std::istream;
using std::ifstream;
using std::ofstream;
using std::endl;
using std::pow;
using std::sqrt;
using std::getline;
using std::string;

const void mergeFile(ifstream& fs1,ifstream& fs2,ofstream& fs3);
//Pre : fs1 & fs2 must exist,fs3 optional
//Post : merge from fs1 and fs2 to fs3,then sort


int main()
{
	ifstream fin1,fin2,fin3;
	ofstream fout;

	cout << "MergeFromFile - By Kudy" << endl;

	fin1.open("intnum1.txt");
	fin2.open("intnum2.txt");
	fout.open("intnum3.txt");

	if(fin1.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin2.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fout.fail())
	{
		cout << "Fout.Fail()";
		exit(1);
	}

	mergeFile(fin1,fin2,fout);

	fin1.close();
	fin2.close();
	fout.close();
//Actually end before this point,but need a print-to-screen version :
	fin1.open("intnum1.txt");
	fin2.open("intnum2.txt");
	fin3.open("intnum3.txt");

	if(fin1.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin2.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}

	if(fin3.fail())
	{
		cout << "Fin.Fail()";
		exit(1);
	}
	cout << "intnum1 : " << endl;
	int next;
	while(fin1 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
	cout << "intnum2 : " << endl;
	while(fin2 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
	cout << "intnum3 : " << endl;
	while(fin3 >> next)
	{
		cout << next << " ";
	}
	cout << endl;
//End of print-to-screen part
	return 0;
}

const void mergeFile(ifstream& fs1,ifstream& fs2,ofstream& fs3)
{
	int next1,next2;
	bool theend = false;
	bool eof1used = false;
	bool eof2used = false;
	fs1 >> next1;
	fs2 >> next2;

	while(!theend)
	{
		if(next1 <= next2 && !fs1.eof() && !fs2.eof())
		{
			fs3 << next1 << " ";
			fs1 >> next1;
		}
		else if(next1 > next2 && !fs1.eof() && !fs2.eof())
		{
			fs3 << next2 << " ";
			fs2 >> next2;
		}
		else if(fs1.eof() && !fs2.eof())
		{
			if(next1 <= next2 && !eof1used)
			{
				fs3 << next1 << " ";
				eof1used = true;
				fs3 << next2 << " ";
				fs2 >> next2;
				if(fs2.eof())
					fs3 << next2 << " ";
			}
			else
			{
				fs3 << next2 << " ";
				fs2 >> next2;
				if(fs2.eof())
					fs3 << next2 << " ";
			}
		}
		else if(fs2.eof() && !fs1.eof())
		{
			if(next2 <= next1 && !eof2used)
			{
				fs3 << next2 << " ";
				eof2used = true;
				fs3 << next1 << " ";
				fs1 >> next1;
				if(fs1.eof())
					fs3 << next1 << " ";
			}
			else
			{
				fs3 << next1 << " ";
				fs1 >> next1;
				if(fs1.eof())
					fs3 << next1 << " ";
			}
		}
		else
			theend = true;
	}
}


is this ok now ? I need a better algorithm or techniques,could sb tell me ?
Last edited on
Could sb help ? mergeFile only,the better techniques are needed...I did this myself and without skilled progrmmer this could never be better
Topic archived. No new replies allowed.