I/O program keeps failing

Whenever I compile and run my code it fails after I input my file names. I am confused as to why this keeps happening, any help would be appreciated. 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
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
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
// file IO version 1: files are opened in main function
#include <iostream>
#include <fstream>	// for ifstream and ofstream classes
#include <cassert>	// for assert() macro
#include <cstdlib>	// for exit()
#include <cmath>
using namespace std;

class rational
{
	friend istream& operator>>(istream&, rational&);
	// User is prompted to enter values for numerator then denominator of a rational number
	//  Precondition: denominator of rational number must not be zero
	// Postcondition: reference rational object passed to the function is filled with values entered by user

	friend ostream& operator<<(ostream&, rational&);
	// Postcondition: displays the contents of the rational object passed to the function 
	//  Must be displayed in the format of  a / b, e.g., 1 / 2,  -5 /9 (not 5 / -9), 1 / 4 (not 2 / 8), etc.
	//  Moreover, if the rational number is 1, display just 1 (not 1 / 1 or 5 / 5, etc.). If the rational number is 0 / 5, etc., display just 0.

public:
	rational();
	// default constructor
	// Postcondition: declared rational object is initialized to 1 (i.e., 1 / 1)

	rational(int aa, int bb);
	// second constructor
	// Postcondition: numerator & denominator of the declared rational object is initialized to parameters aa and bb, respectively; 
	//                          program exits if bb = 0

	int getNum();
	// Accessor 
	// Postcondition: returns the numerator of the calling rational object

	int getDenom();
	// accessor
	// Postcondition: returns the denominator of the calling rational object

	void set(int aa, int bb);
	// Postcondition: calling rational object is set to aa / bb

	rational operator+(const rational &r2) const;
	// Postcondition: sum of calling rational object and r2 is returned (notice the return type is rational!)

	rational operator-(const rational &r2) const;
	// Postcondition: (calling rational object - r2) is returned 

	rational operator*(const rational &r2) const;
	// Postcondition: product of calling rational object and  r2 is returned
 
	rational operator/(const rational &r2) const;
	// Postcondition: (calling rational object / r2) is returned

	int operator>(const rational&r2) const;
	// Postcondition: returns 1 if calling object is greater than r2; 0 if r1 is equal to r2; -1 is r1 is less than r2 
private:
	int GCD() const;
	// Helper function; not intended for clients of class, so  it is kept in private section. You must use the Euclidean algorithm. 
	// Postcondition: returns the "greatest common divisor" between the numerator and denominator of the calling rational object
	int a;	// numerator
	int b;	// denominator
};

// External function prototypes
int fillArrayFromDiskFile(istream &fin, rational r[]);		
//  Precondition: address & physical size of the rational array declared in the calling function must be passed to the function
// Postcondition: returns the actual # of rational numbers entered by user which must be less than or equal to size

void displayArray(rational r[], int n);
// Postcondition: display n rational numbers

void writeArrayToDiskFile(ostream &fout, rational r[], int n);
// Postcondition: 

void selectionSort(rational r[], int n);
//  Precondition: address of the rational array declared in the calling function and the # of elements to be sorted must be 
//                          passed to the function
// Postcondition: n rational number is the array are sorted in ascending order

int findSmallestRationalNumber(rational r[], int first, int n);
//  Precondition: accepts address, subscript value of the first element of the unsorted sub-list, and the # of array elements n 
// Postcondition: returns subscript value of the smallest rational number in the unsorted sub-list of the array

void swap(rational &r1, rational &r2);
// Postcondition: contents of memory locations referenced by r1 and r2 are swapped

// main function

rational::rational()
{
}

rational::rational(int aa, int bb)
{
	if (b == 0)
	{
		cout << "Denominator cannot equal 0\n";
		
		exit(1);
	}
	
	a = aa;
	b = bb;
}

int rational :: getNum()
{
	return (a);
}

int rational :: getDenom()
{
	return (b);
}

void rational::set(int aa, int bb)
{
	cout << "Enter numerator and denominator: \n";
	cin >> aa >> bb;
}

int rational::operator>(const rational&r2) const
{
	double r1total, r2total;
	
	r1total = (double) a/b;
	r2total = (double) r2.a/r2.b;
	
	if (r1total > r2total)
		return 1;
	else if (r1total == r2total)
		return 0;
	else 
		return -1;
}

int rational::GCD() const
{
	int n = abs(a);
	int d = abs(b);
	
	while(d != 0)
	{
		int temp = d;
		d = n % d;
		n = temp;
	}
	
	return n;
}

istream& operator>>(istream &in, rational &r2)
{
	in >> r2.a >> r2.b;
	
	return in;
}

ostream& operator<<(ostream &out, rational &r2)
{
	int gcd = r2.GCD();
	
	if (r2.b < 0)
	{
		r2.b = -(r2.b);
		r2.a = -(r2.a);
	}
	out << r2.a / gcd << "/" << r2.b / gcd;
	
	return out;
}

int fillArrayFromDiskFile(istream &fin, rational r[], int size)
{
	int i = 0;
	char more = 'Y';
	
	cout<<"You may enter up to " << size <<" rational numbers:\n\n";
	
	for(i < size; ++i;)
	{
		do
		{
			fin >> r[i];
			cout << endl;
			cout << "More rational numbers (Y/N)? ";
			cin >> more; 
			cout << endl << endl;
		}
		while(more == 'Y'|| more == 'y');
	}
	return (i);
}

void displayArray(rational r[], int n)
{   
	cout << endl;
	
	for(int i = 0; i < n; i++)
	{
		cout << r[i];
	}
	
}

void writeArrayToDiskFile(rational r[], int n)
{
	for (int i = 0; i < n; i++)
	{
		cout << r[i];
		cout << " ";
	}
}

void selectionSort(rational r[], int n)
{
	int i, pos;
	
	for(i = 0; i < n; i++)
	{
		pos = findSmallestRationalNumber(r, i, n);
		swap(r[i], r[pos]);
	}
	
}

int findSmallestRationalNumber(rational r[], int first, int n)
{
	int pos = first;
	rational smallest = r[pos];
	
	for(int i = first + 1; i < n; i++)
	{
		if((r[i] > smallest) == -1)
		{
			smallest = r[i];
			pos = i;
		}
	
	}
	return pos;
}

void swap(rational &r1, rational &r2)
{
	rational temp;
	
	temp = r1;
	r1 = r2;
	r2 = temp;
	
}


int main()
{
	ifstream fin;		// fin is an ifstream object used to call member functions open(), close(), fail(), etc
   	ofstream fout;	// fout is an ofstream object used to call member function close(), fail(), etc.
	
	const int SIZE = 50, FILE_NAME_SIZE = 16;
	rational r[SIZE];
	char inputFileName[FILE_NAME_SIZE], outputFileName[FILE_NAME_SIZE];
	
	cout << "Enter the name of the input disk file (up to 15 characters): ";
	cin >> inputFileName;
	cout << "Enter the name of the output disk file (up to 15 characters): ";
    cin >> outputFileName;
	
	fin.open(inputFileName);
    if (fin.fail())
    {
    	cout << "Input file opening failed.\n";
    	exit(1);
	}
	
	int insize = fillArrayFromDiskFile(fin, r, SIZE);
    
    cout << "Aray contains " << insize << " rational numbers read from the disk file named in.txt" << endl;
    
    cout << "Before sort, the array contains:\n";
    for (int i = 0; i < insize; i++)
    {
    	displayArray(r, insize);
	}
	
	for (int x = 0; x < insize; x++)
	{
		selectionSort(r, insize);
	}
	
	cout << "After sort, the array cotains:\n";
	for (int y = 0; y < insize; y++)
	{
		displayArray(r, insize);
	}
	
	cout << "Open output disk file to store the sorted array:\n";
	
    fout.open(outputFileName);
	if (fout.fail())
	{
		cout << "Output file opening failed.\n";
		exit(1);
	}
    
    cout << "The contents of the array is now written to a disk file named out.txt\n";
    
    cout << "We now open the out.txt, read and display its contents:\n";
    
    writeArrayToDiskFile(r, insize);

	fin.close();
	fout.close();

		
	return 0;
}
Whenever I compile and run my code it fails after I input my file names.


You have an infinite outer loop in fillArrayFromDiskFile, and your inner loop repeatedly writes values to the same element of r.

In the future, please be more specific than "my code fails." It helps anyone interested in answering get to the meat of the matter.
Last edited on
Topic archived. No new replies allowed.