I am trying to write a function that will count test scores that fall in a specific range(90-100, 89-80, 79-70, 69-60 and 60 or below) that are stored in a two dimensional array. Also, I am supposed to write a function that will do the same as above, only this one will count the number of students whose test score average will fall into each of those ranges. Here is the code I have so far:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

void storeData(string studentNames[10], int scores[10][5]);
void calculateData(int scores[10][5],double average[10], int& i, int& j, double& classAverage);
void outputResults(double average [10], int& i, string studentNames[10], double& classAverage);


int main()
{
	string studentNames[10];
	int scores[10][5];
	double average[10];
	int i, j;
	double classAverage;
	storeData(studentNames, scores);
	calculateData(scores, average, i, j, classAverage);
	outputResults(average, i, studentNames, classAverage);
}	
void storeData(string studentNames[10], int scores [10][5])
{
	ifstream inFile;
	inFile.open ("data.txt");
	if (!inFile)
	{
		cout << "Unable to open file." << endl;
		cout << "Program will now terminate" << endl;
		system("exit:");
	}
	int i, j;
	for(i = 0; i < 10; i++)
	{
		inFile >> studentNames[i];
		for(j = 0; j < 5; j++)
		{
			inFile >> scores[i][j];
		}

	}
	inFile.close();
}

void calculateData(int scores[10][5],double average[10], int& i, int& j, double& classAverage)
{
	int sum = 0;
	for(i = 0; i < 10; i++)
	{
		sum = 0;
		for(j = 0; j < 5; j++)
		{
			sum = sum + scores[i][j];
		}
		average[i] = sum / 5;
	}
	classAverage = (scores[0][0] + scores[0][1] + scores[0][2] + scores[0][3] + scores[0][4] + scores[1][0] + scores[1][1] + scores[1][2] + scores[1][3] + scores[1][4] + scores[2][0] + scores[2][1] + scores[2][2] + scores[2][3] + scores[2][4] + scores[3][0] + scores[3][1] + scores[3][2] + scores[3][3] + scores[3][4] + scores[4][0] + scores[4][1] + scores[4][2] + scores[4][3] + scores[4][4] + scores[5][0] + scores[5][1] + scores[5][2] + scores[5][3] + scores[5][4] + scores[6][0] + scores[6][1] + scores[6][2] + scores[6][3] + scores[6][4] + scores[7][0] + scores[7][1] + scores[7][2] + scores[7][3] + scores[7][4] + scores[8][0] + scores[8][1] + scores[8][2] + scores[8][3] + scores[8][4] + scores[9][0] + scores[9][1] + scores[9][2] + scores[9][3] + scores[9][4]) / 50;
}

void outputResults(double average [10], int& i, string studentNames[10], double& classAverage)
{

	for(i = 0; i < 10; i++)
	{
		cout << studentNames[i] << " ";
		if (average[i] >= 90)
		{
			cout << "Grade = A" << endl;
		}
		else if (average[i] >= 80)
		{
			cout << "Grade = B" << endl;
		}
		else if (average[i] >= 70)
		{
			cout << "Grade = C" << endl;
		}
		else if (average[i] >= 60)
		{
			cout << "Grade = D" << endl;
		}
		else
		{
			cout << "Grade = F" << endl;
		}

	}
	cout << fixed << showpoint << setprecision(2);
	cout << "The class average is " <<  classAverage;
}

void countScores(int& i, int& j, int scores[10][5])
{

}

void countAverage(int& i, int& j, double average[10])
{

}

I have no clue as to how to even begin these two functions. I am very much a beginner to c++, so any help would be greatly appreciated. Thanks in a advance.

Hey By the Blood (Can I address you as just "by"? :-) ).

A couple of things, when setting up loops involving arrays, instead of settings up the for loop as a hard coded number of loops (i.e.

;j < 5;

), I'd use

i < scores.size()

and

j < scores[i].size()

. It's good form and makes it easier to make changes to the size of the arrays without having to change your loops.

I'd also declare your i's and j's in your for loops (i.e.

for(int i = 0; i < scores.size(); ++i)

), if you have them declared outside of the loops you could wind up with some issues if you use them elsewhere.

When you go to perform the average, it would be better to either create a function to do it so you keep a "separation of duties" and make it easier to read. You would be better off using a loop and counter variable to sum up the values of the grades and do the averaging.

In order to count the ranges of grades, I'd create a function that has access to 5 variables that keep track of each grade range and increment the correct variable as a loop goes through the arrays therefore you can get a count of each range.

The second function can do something similar, except it averages all of the grades from the student and then increments a variable to keep track of the number of students in each grade range.

I hope that helps,
Andy

Edited 5 Years Ago by laosland: Added code tags

Part of the above advice is not pertinent to your problem or your code. i < scores.size() does not give you size of your array. It would be a good idea to make the loop limit test in your functions use variables for rows and columns, and pass those sizes as function parameters. This would make your functions more general and not limited to very specific problem size.

That said, the crux of your problem is to walk through the matrix, counting up scores as you go along. Your calculateData() is finding each student's average in 51-59, good.

Line 60 is a horrible, horrible way to find the overall class average! (Can you readily prove you did not make any typographical errors in the indexes?) You could, as you are adding each student's scores for individual averages, also add those scores to a class total, to be divided once all students have been added. Or have another nested loop set that does sums up all the scores.

Your two count functions then need to be given either the array of averages or the full matrix, and the corresponding array to store the counts. Since you are storing only five counts for each value (averages or individual scores) you need only 5 element arrays. You could use an if..else if block as you did for your output to increment the values in the counting arrays for each applicable score, or devise a mathematical way to index into the counting arrays and increment the appropriate element.

My apologies, you're right about .size() not returning the number of elements. I've been using Vectors so long that I had forgotten that.
Andy

Part of the above advice is not pertinent to your problem or your code. i < scores.size() does not give you size of your array. It would be a good idea to make the loop limit test in your functions use variables for rows and columns, and pass those sizes as function parameters. This would make your functions more general and not limited to very specific problem size.

That said, the crux of your problem is to walk through the matrix, counting up scores as you go along. Your calculateData() is finding each student's average in 51-59, good.

Line 60 is a horrible, horrible way to find the overall class average! (Can you readily prove you did not make any typographical errors in the indexes?) You could, as you are adding each student's scores for individual averages, also add those scores to a class total, to be divided once all students have been added. Or have another nested loop set that does sums up all the scores.

Your two count functions then need to be given either the array of averages or the full matrix, and the corresponding array to store the counts. Since you are storing only five counts for each value (averages or individual scores) you need only 5 element arrays. You could use an if..else if block as you did for your output to increment the values in the counting arrays for each applicable score, or devise a mathematical way to index into the counting arrays and increment the appropriate element.

This article has been dead for over six months. Start a new discussion instead.