Read until end of data, not end of file...

Hi all. Long time lingerer, first time poster.

I'm having a problem with a roster program assignment. I was given two files to read, one for each baseball team. The data is formatted as follows:
PlayerNumber PlayerName Homeruns
Each file can contain up to 20 lines of data, but they may contain less. Say one of these file contains only 16 lines of data, then the remaining 4 lines are blank(with \n in each one).

My problem is reading until the end of the data, not the end of the file.
The assignment specs are to use the functions and variables that the instructor provided and fill in the code. Therefore, what you see in my code below is what I have to work with. I can't change anything.

The code reads the data into 3 arrays and then sorts the arrays in two different ways.

Here's my code:

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

// function prototypes
int readRoster(char[][20], int[], int[]);
void printRoster(char[][20], int[], int[], int);
void sortNumber(char[][20], int[], int[], int);
void sortHR(char[][20], int[], int[], int);

void main()
{
	// variables
	char name[20][20]; // array to hold player's first and last name
	int hr[20]; // array to hold homeruns
	int number[20]; // array to hold player's number
	int numberOfPlayers; // number of players

	// read in the players
	numberOfPlayers = readRoster(name, number, hr);
	printRoster(name, number, hr, numberOfPlayers);

	sortNumber(name, number, hr, numberOfPlayers);
	printRoster(name, number, hr, numberOfPlayers);

	sortHR(name, number, hr, numberOfPlayers);
	printRoster(name, number, hr, numberOfPlayers);
}

int readRoster(char name[][20], int number[], int hr[])
{	
	const int FILENAME_SIZE = 50;
	int size = 0; // 
	int numberOfPlayers = 0;	// holds the number of players listed in the file
	char filename[FILENAME_SIZE];	// holds the filename entered by the user
	char firstName[20]; // array to hold player's first name
	char lastName[20]; // array to hold player's last name
	ifstream inputFile;	// file stream object

	// prompt user for the filename
	cout << "Enter the name of the file: ";
	cin >> filename;

	// open the file
	inputFile.open(filename, ios::in);

	// check file
	while (!inputFile)
	{
		cout << filename << " could not be opened.\n";
		cout << "Please re-enter the name of the file: ";
		cin >> filename;
	}

	cout << "Reading data from the file...\n";
	// read all of the players in the file

	while (!inputFile.eof())
	{
		for (int i = 0; i < 20; i++)
		{
			inputFile >> number[i];
			inputFile >> firstName >> lastName;
			inputFile >> hr[i];

			strcpy(name[i], firstName);
			strcat(name[i], " ");
			strcat(name[i], lastName);

			numberOfPlayers++;
		}
	}
	return numberOfPlayers;
	inputFile.close();
}

void printRoster(char name[][20], int number[], int hr[], int numPlayers)
{
	cout << left;
	cout << endl;
	cout << setw(5) << "# " << setw(22)<< "Name" << setw(15) << "Homeruns" << endl;
	cout << "====================================" << endl;
	for (int i = 0; i < numPlayers; i++)
		cout << right << setw(2) << number[i] << "   " << left << setw(20) << name[i] << "  (" << right << setw(2) << hr[i] << ")" << endl;
}

// sortNumber will sort the roster in ascending order by players' numbers
void sortNumber(char name[][20], int number[], int hr[], int numPlayers)
{
	// variables to hold temporary data when sorting the roster
	int tempNumber;
	int tempHR;
	char tempName[20];
	for (int i = 0; i < numPlayers - 1; i++)
	{
		// variable to hold the current lowest number for players' numbers
		int currentMin = number[i];
		// variable to hold the index for the lowest number
		int currentMinIndex = i;

		for (int j = i + 1; j < numPlayers; j++)
		{
			if (currentMin < number[j])
			{
				currentMin = number[j];
				currentMinIndex = j;

				tempNumber = number[i];
				number[i] = number[j];
				number[j] = tempNumber;
				
				strcpy(tempName, name[i]);
				strcpy(name[i], name[j]);
				strcpy(name[j], tempName);

				tempHR = hr[i];
				hr[i] = hr[j];
				hr[j] = tempHR;
			}
		}
	}
}

// sortHR will sort the roster in descending order by players' homeruns
void sortHR(char name[][20], int number[], int hr[], int numPlayers)
{
	// variables to hold temporary data when sorting the roster
	int tempNumber;
	int tempHR;
	char tempName[20];

	for (int i = 0; i < numPlayers - 1; i++)
	{
		// variable to hold the current highest number for players' homeruns
		int currentMax = hr[i];
		// variable to hold the index for the highest homeruns
		int currentMaxIndex = i;

		for (int j = i + 1; j < numPlayers; j++)
		{
			if (currentMax < hr[j])
			{
				currentMax = hr[j];
				currentMaxIndex = j;

				tempHR = hr[i];
				hr[i] = hr[j];
				hr[j] = tempHR;

				tempNumber = number[i];
				number[i] = number[j];
				number[j] = tempNumber;
				
				strcpy(tempName, name[i]);
				strcpy(name[i], name[j]);
				strcpy(name[j], tempName);
			}
		}
	}
}


Here is the output:

Enter the name of the file: sox.dat
Reading data from the file...

# Name Homeruns
====================================
12 A.J. Pierzynski (14)
24 Joe Crede ( 4)
15 Tadahito Iguchi ( 6)
14 Paul Konerko (31)
5 Juan Uribe (20)
23 Jermaine Dye (28)
22 Scott Podsednik ( 2)
25 Jim Thome (35)
27 Josh Fields (23)
17 Darin Erstad ( 4)
20 Rob Mackowiak ( 6)
26 Andy Gonzalez ( 2)
1 Danny Richar ( 6)
8 Alex Cintron ( 2)
19 Luis Terrero ( 5)
31 Ryan Sweeney ( 1)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)

# Name Homeruns
====================================
31 Ryan Sweeney ( 1)
27 Josh Fields (23)
26 Andy Gonzalez ( 2)
25 Jim Thome (35)
24 Joe Crede ( 4)
23 Jermaine Dye (28)
22 Scott Podsednik ( 2)
20 Rob Mackowiak ( 6)
19 Luis Terrero ( 5)
17 Darin Erstad ( 4)
15 Tadahito Iguchi ( 6)
14 Paul Konerko (31)
12 A.J. Pierzynski (14)
8 Alex Cintron ( 2)
5 Juan Uribe (20)
1 Danny Richar ( 6)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)

# Name Homeruns
====================================
25 Jim Thome (35)
14 Paul Konerko (31)
23 Jermaine Dye (28)
27 Josh Fields (23)
5 Juan Uribe (20)
12 A.J. Pierzynski (14)
15 Tadahito Iguchi ( 6)
20 Rob Mackowiak ( 6)
1 Danny Richar ( 6)
19 Luis Terrero ( 5)
17 Darin Erstad ( 4)
24 Joe Crede ( 4)
8 Alex Cintron ( 2)
26 Andy Gonzalez ( 2)
22 Scott Podsednik ( 2)
31 Ryan Sweeney ( 1)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)
-858993460 (-858993460)

As you can see, it's reading in the last 4 blank lines.
Any suggestions?
I think the simplest way is to "clean up" your arrays before using them like this:

1
2
3
4
5
6
7
for (short i = 0; i < 20; i++) {
      hr [i] = 0;
      number [i] = 0; 
}
for (short j = 0; j < 20; j++)
       for (short i = 0; i < 20; i++)
              name [i] [j] = ' ';

now when you clean it up (set all to int zerro and char to whitespace) you will know for each array where is the end
now use some if statements to break when get to zerro or ' ' for example:
1
2
if (name [i] [j] = ' ') // do someting or skip
if ( number [i] = 0;) // do something or skip 

Last edited on
Topic archived. No new replies allowed.