File adding too many values to array

I am trying to input values of type double into an array from a file. The array is allowed to hold up to 20 rows and must have 5 columns. It can, however, have less than 20 rows.

The problem is that once the loop reaches the end of the file it does not stop and instead continues going, filling the next, however many rows up to 20, with garbage numbers. How would I go about making it stop adding values to the array after it has read the last value in the file? I tried using the eof function but it does not seem to work. Any help would be much appreciated. Thanks!

The problem happens in the readFile function.

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

const int MAX_COLUMNS = 5;

int readFile(double values[][MAX_COLUMNS], int maxRows, string inputFileName);

int main()
{
	const int MAX_ROWS = 20;
	string inputFileName;
	double grades[MAX_ROWS][MAX_COLUMNS];

	cin >> inputFileName;

	int actualRows = readFile(grades, MAX_ROWS, inputFileName);

	if (actualRows == -1)
	{
		cout << "File \"" << inputFileName << "\" could not be opened" << endl;
		return 0;
	}
	else if (actualRows == 0)
	{
		cout << "The input file \"" << inputFileName << "\" did not contain any data" << endl;
		return 0;
	}
	else
	{
		return 0;
	}
}

int readFile(double values[][MAX_COLUMNS], int maxRows, string inputFileName)
{
        ifstream inFS;
	int actualRows = 0, columns = 1, r = 0, c = 0;

	inFS.open(inputFileName);

	if (!inFS.is_open())
	{
		return -1;
	}

	while (!inFS.eof())
	{
		for (int r = 0; r < maxRows; r++)
		{
			for (int c = 0; c < MAX_COLUMNS; c++)
			{
				inFS >> values[r][c];
				columns = c + 1;
				cout << values[r][c] << " ";
			}
			cout << endl;
			actualRows++;
		}
	}

	inFS.close();

	cout << "Processing " << actualRows << " rows, and " << columns << " columns" << endl;

	if (actualRows <= 1 && columns < 5)
	{
		return 0;
	}

	return actualRows;
}
Can you provide an example of the file you're reading from?
Those are the numbers I am reading in.

61.4 89.5 62.6 89.0 100.0
99.5 82.0 79.0 91.0 72.5
The while loop wrapped around the nested for loop doesn't make much sense, it only needs two levels of looping, not three.


Here, increment the row count only after successfully reading each group of 5. If less than five values could be read, the count is not incremented.

The outer loop will terminate when either: array is already full or file status is 'fail'.

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
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>

using namespace std;

const int MAX_COLUMNS = 5;

int readFile(double values[][MAX_COLUMNS], int maxRows, string inputFileName);
void printArray(double values[][MAX_COLUMNS], int numRows);


int main()
{
    const int MAX_ROWS = 20;
    string inputFileName;
    double grades[MAX_ROWS][MAX_COLUMNS];

    cin >> inputFileName;

    int actualRows = readFile(grades, MAX_ROWS, inputFileName);

    if (actualRows == -1)
    {
        cout << "File \"" << inputFileName << "\" could not be opened" << endl;
        return 0;
    }
    else if (actualRows == 0)
    {
        cout << "The input file \"" << inputFileName << "\" did not contain any data" << endl;
        return 0;
    }

    printArray(grades, actualRows);

    return 0;
}

int readFile(double values[][MAX_COLUMNS], int maxRows, string inputFileName)
{

    ifstream inFS(inputFileName);

    if (!inFS)
    {
        return -1;
    }

    int actualRows = 0;

    while (actualRows  < maxRows && inFS)
    {
        for (int c = 0; c < MAX_COLUMNS; c++)
        {
            inFS >> values[actualRows][c];
        }
        
        if (inFS)
            actualRows++;
    } 

    cout << "Processing " << actualRows << " rows, and " << MAX_COLUMNS << " columns" << endl;

    return actualRows;
}


void printArray(double values[][MAX_COLUMNS], int numRows)
{
    for (int r = 0; r < numRows; ++r)
    {
        for (int c = 0; c < MAX_COLUMNS; c++)
        {
            cout << setw(10) << values[r][c];
        }
        cout << '\n';
    } 

}
That actually makes a lot of sense. Thank you very much for your help Chervil.
Registered users can post here. Sign in or register to post.