I am completly lost with arrays. I have scoured my book and the exaamples it gives are way to simple. I can wrerite them like those in the books, but I cannot seem to get the real problem to work. Also I am doing ifstream and ofstream so I cannot really see what is happening. I printed to screen once and it was just a bunch of garbage. Here is the problem: I have to take input from the file PianoREV.data and output it to Report.out. I need to setup parallel partially filled arrays for the contestant id's, student level, composision difficulty rating, num judges and overall averages. I need two dimensional arrays for the judge ids judges scores and weighted scores. Then a print report fucntion comes and prints it all. I have not attempted to write this as i cannot get the arrays to work to begin with. Here is an example of the PianoREV.

6010 1 1.3
23 7.0
25 8.5
34 7.0
12 7.5
-1
6012 1 1.2
23 7.5
34 7.0
45 7.0
50 7.5
-1

The first number is the player id. the second the proficiency level, the third is the weight factor, followed by judge and then score. I had a lot of help with psuedo code on the first assignment based on this task and would depply appreciate some more. MY teacher is really not helping any of us. Half the class has dropped and the other half is failing. Anyways here is what i have so far. Am I even going in the right direction?

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
const int MAXMEMBERS = 25;
int ReadScores (ifstream& fin, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS]);

int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];

const int MAXJUDGES = 7;
int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
	fout.open("Report.out");
	if (fout.fail())
	{
		cout << "Error: Output File";
		exit (1);
	}
ReadScores (fin, pianoPlayer, score);
fin.close();
fout.close();
}

int ReadScores (ifstream& fin, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS])
{
	int countPlayers = 0;
	while (countPlayers < MAXMEMBERS && (fin >> pianoPlayer[MAXMEMBERS]))
	{
		int i = 0;
		int judgeNumber[i];
		fin >> profLevel[countPlayers];
		fin >> weightFactor[countPlayers];
		while (judgeNumber[i] != -1)
		{
			for(i = 0; i<MAXJUDGES;i++)
			{
				fin >> judgeNumber[i];
				fin >> score[i];
				fin >> judgeNumber[i];
			}
		}
	}
	return countPlayers;
}

Recommended Answers

All 50 Replies

So, according to your description
Player ID = 6010
Proficiency Level = 1
Weight Factor = 1.3
Judge = 23
Score = 7.0

Then the next set is
Player ID = 25
Proficiency Level = 8.5
Weight Factor = 34
Judge = 7.0
Score = 12


That doesn't look right to me because the numbers in the first set are not the same type as those in the second set. You need to clarify what that data rally means before you can write a program to read them.

The portion of the input file posted contains the data for two piano players, one with number 6010 and one with number 6012. The data is delimited by player with a -1. In this example each player has proficiency of 1 but one has weight factor 1.2 and the other weight factor 1.3. Each player received scores from 4 judges with the each judges number and score from that judge listed on a separate line. I assume that in other parts of the file a player may have scores from a different number of judges, hence the need to delineate player data by the -1 flag, but maybe it's just a learning exercise in how to identify and deal with delimeters when reading a file.

What I don't understand is how many arrays are needed:

>>I need to setup parallel partially filled arrays for the contestant id's, student level, composision difficulty rating, num judges and overall averages.

Does this imply 5 arrays are needed, one for each of the above sets of data?

And what do you mean by partially filled? Are you supposed to use tables of a given size but only certain elements within the table are going to be used---how will you know which elements are to be used and which aren't---by player number, judge number, develop a hash function?


Then what does this mean:

>>I need two dimensional arrays for the judge ids judges scores and weighted scores.

Are you supposed to read through the data for all scores from a given judges and place them in a single two dimensional array of type double?

if you know how to write a c++ class, you can do the project with no c-style arrays at all. Two classes and a vector should do the job.

class judge
{
public:
	long	JudgeID;
	float	weight;
};

class PianoRE
{
public:
	PianoRE() {PlayerID = Proficiency = 0; WeightFactor = 0.0f;}
	void SetPlayerID(long id) {PlayerID = id;}
	long GetPlayerID() {return PlayerID;}
	void SetProficiendy(long prof) {Proficiency = prof;}
	long GetProficiency() {return Proficiency;}
	void SetWeight(float w) {WeightFactor = w;}
	float GetWeight() {return WeightFactor;}
	void SetJudge(const judge& j) {judges.push_back(j);}
	const vector<judge>& GetJudges() {return judges;}

protected:
	long	PlayerID;
	long	Proficiency;
	float	WeightFactor;
	vector<judge> judges;

};

or if you cannot yet handle that, you can create a structure and make a linked list of those structures

struct judge
{
	long	JudgeID;
	float	weight;
        struct judge* next;
};

struct PianoRE
{
	long	PlayerID;
	long	Proficiency;
	float	WeightFactor;
	struct judges*  HeadJudge;
        struct PianoRE* next;
};

now just learn how to do linkes lists, and again you need not use
any c-style arrays.

Hey lsu420luv, I would suggest the following way of implementing this part of your project. You would have to implement the output file logic yourself.

typedef std::map<int, float> Ratings; // Use this type to store judge ratings
typedef std::vector<PianoStudent> Players; // Use this type to store PianoStudents

struct PianoStudent
{
	int player_id;
	int player_proficiency;
	float weight_factor;
	Ratings judge_ratings;
};

int main ()
{
	std::ifstream fin("PianoREV.data");

	if (!fin) // Check if file open failed
	{
		cout << "Error: Input File";
		return 1;
	}

	Players students; // PianoStudent vector
	PianoStudent ps;

	while (fin)
	{
		if (!(fin >> ps.player_id))
			break;
		if (!(fin >> ps.player_proficiency))
			break;
		if (!(fin >> weight_factor))
			break;

		// Process the judges
		while (fin)
		{
			int judge_id;
			float rating;
			if (!(fin >> judge_id) || judge_id == -1)
				break;
			if (!(fin >> rating))
				break;
			ps.judge_ratings.insert(std::make_pair(judge_id, rating)); // Add the judge rating
		}
		students.push_back(ps); // Add the student to the vector
	}

	// Print out all the students
	cout << "Total students: " << students.size() << endl;
	for (Players::iterator iter = students.begin(); iter != students.end(); ++iter)
	{
		cout << "Player ID: " << iter->player_id << endl
			<< "Player Proficiency: " << iter->player_proficiency << endl
			<< "Weight Factor: " << iter->weight_factor << endl;
		for (Ratings::iterator jter = iter->judge_ratings.begin(); jter != iter->judge_ratings.end(); ++jter)
		{
			cout << "Judge ID: " << jter->first
				<< " Rating: " << jter->second << endl;
		}
	}

	return 0;
}

I felt that you tried your best and I know there are many lecturers out there who don't do their job. I hope this would be of good help to you. I wrote the code to print out the information contained within the PianoStudent as a reference on how to retrieve the values from the vector and map . If you encounter any further problems, or if anyone has better suggestions to this solution, feel free to point them out.

I am not supposed to know how to do vectors or structures yet. Lerner was right in his assumptions. They are supposed to be loaded into 5 partially filled arrays. Some of them hitting the max number of judges being 7 and some not. The judges is's the judges scores and the weighted scores are scored in seperate 2-d arrays that store the multiple scores for that player id. I hope this answers the questions.


Are you supposed to read through the data for all scores from a given judges and place them in a single two dimensional array of type double?

I am supposed to read through the scores for all judges for one player and score that in a 2-d array. Also the weighted scores and the jude ids.

That's possible, but it could become very messy. It might be better to have three arrays, one for the judge ID, another for the score, and the last for the student ID. This student ID will allow you to match up the judge/score to the student's statistics, like proficiency and weight factor. If you could use pointers, dynamic means to allocating the memory is preferred because you do not know how large your future data files might be.

I thought lecturers wouldn't bother on structs, vectors and so on as long as the whole thing works properly. In fact I believe that most lecturers wouldn't bother to look at code if it is possible, say, unless you are supposed to submit an implementation of an algorithm or something somewhere along that line.

That's possible, but it could become very messy. It might be better to have three arrays, one for the judge ID, another for the score, and the last for the student ID. This student ID will allow you to match up the judge/score to the student's statistics, like proficiency and weight factor. If you could use pointers, dynamic means to allocating the memory is preferred because you do not know how large your future data files might be.

I thought lecturers wouldn't bother on structs, vectors and so on as long as the whole thing works properly. In fact I believe that most lecturers wouldn't bother to look at code if it is possible, say, unless you are supposed to submit an implementation of an algorithm or something somewhere along that line.

In the assignment sheet it requires the 5 arrays. She does do shit messy. She is an awful teacher I think. This whole class is code.

Five arrays... well you could try your original method I guess. What more can I say since the situation is like that...

Here is what I have been working on. It will not print to the report.out. It does not have all the arrays built, but it should fill the ones necessary at least to output some text to file. What am I doing wrong here?

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
const int MAXMEMBERS = 25;
const int MAXJUDGES = 7;
int ReadScores (ifstream& fin, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
			       int judgeNumber[MAXMEMBERS][MAXJUDGES]);

int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS][MAXJUDGES];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];
int judgeNumber[MAXMEMBERS][MAXJUDGES];
int category;  //category of music the students are playing
//index of student id's
 //index of something
int judgeCount[MAXMEMBERS];
int numPlayers = 0;
int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
	fout.open("Report.out");
	if (fout.fail())
	{
		cout << "Error: Output File";
		exit (1);
	}
ReadScores (fin, pianoPlayer, score, judgeNumber);
numPlayers = ReadScores (fin, pianoPlayer, score, judgeNumber);
fin.close();
fout.close();
}

int ReadScores (ifstream& fin, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES], 
			       int judgeNumber[MAXMEMBERS][MAXJUDGES])
{
	int i= 0;
	int j= 0;
	fin >> category;
	while (i < MAXMEMBERS && (fin >> pianoPlayer[i]))
	{
		fin >> profLevel[i];
		fin >> weightFactor[i];
		fin >> judgeNumber[i][j];
		while (judgeNumber[i][j] != -1)
		{
			j++;
			i++;
			fin >> score[i][j];
			fin >> judgeNumber[i][j];
		}
	}
	return i;
}
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], int score[MAXMEMBERS][MAXJUDGES],
				int numPlayers)
{
	int i;
	int j;
	for (i = 0; i < numPlayers; i++)
	{
		fout << pianoPlayer[i];
		fout << score[i][j];
		j++;
	}	
	return;
}

I just couted to screen and it is not exiting the while loop when it hits the negative 1. Another things are the arrays filling right and how can i check this.

I have setup the arrays sucessfully I think. At least the score and the player ids. For some reason it is pulling in the negative one before exiting though. Is there a way to avoid this? Here it is

int ReadScores (ifstream& fin, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES], 
				int judgeNumber[MAXMEMBERS][MAXJUDGES])
{
	int i= 0;
	int j= 0; 
	int k= 0; //index judge count
	fin >> category;
	while (fin >> pianoPlayer[i])
	{
		fin >> profLevel[i];
		fin >> weightFactor[i];
		fin >> judgeNumber[i][j];
		while (judgeNumber[i][j] != -1)
		{
			fin >> score[i][j];
			fin >> judgeNumber[i][j];
			j++;			
		}
	judgeCount[i] = j;	
	i++;
	j = 0;
	}
	return i;
}
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				 int numPlayers)
{
	for (i = 0; i < MAXMEMBERS; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i];
		for (j =0; j < MAXJUDGES; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
	}	
	return;
}

Basically after the completion of one cycle the player id becomes the negative one and the all the data becomes off by one each repition. There is something wrong with my loops it is not stopping after the players are read I do not think, but it is not trapped in an infinite loop. I do not know what to do. I think I finnally am getting some grasp on this

It's not printing anything because you did not call the PrintReport method?

Your reading method seems to be flawed. Try this method (it's a modified version what I wrote earlier):

int ReadScores (ifstream& fin)
{
	int i;
	for (i = 0; fin && i < MAXMEMBERS; ++i)
	{
		if (!(fin >> pianoPlayer[i]))
			break;
		if (!(fin >> profLevel[i]))
			break;
		if (!(fin >> weightFactor[i]))
			break;

		// Process the judges
		for (int j = 0; fin; ++j)
		{
			if (j >= MAXJUDGES)
			{
				// If the number of judges overflow the array size,
				// we have to clear off the remaining judge entries
				// so that we can continue reading from the next
				// player entry
				int k;
				if (!(fin >> k) || k == -1)
					break;
				else
					continue;
			}
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
				break;
			if (!(fin >> score[i][j]))
				break;
		}
	}
	return i;
}

Hope this helps.

Oh yes, it would be good to place your ReadScores and PrintReport methods above the main method so that you do not need to pre-declare them.

that rocks. Thank you. I am still running into the problem of it reading 8 judges for every player. It is not exiting at the -1. I see that it is reading until MAXJUDGES has been read. I do not know how to put the while loop in there for sentinal control. Also it is reading 25 players rather than just reading until the last player is processed. How can i get around this. Is there a way to just disply the filled parts or do i have to use the while loop.
Also I am supposed to be calling by reference only. What does this mean?
How do I add up the scores to avereage them? I have been fiddling and I keep on using the wrong values?

Sorry, but I do not fully understand what you have posted (no, I'm not pointing out the spelling mistakes):

I do not know how to put the while loop in there for sentinal control.

What do you mean by "sentinal control"?

Is there a way to just disply the filled parts or do i have to use the while loop.

What do you mean by "disply the filled parts"? What filled parts do you want to display?

Also I am supposed to be calling by reference only. What does this mean?

Honestly I would not know unless you give me the context in which your lecturer placed that statement.

How do I add up the scores to avereage them? I have been fiddling and I keep on using the wrong values?

This is pretty simple. Assume that sid is the array index of the student you want to average the score for.

int numJudges = 0;
double totalScore = 0;
double average = 0;
for (; numJudges < MAXJUDGES && judgeNumber[sid][numJudges] != -1; ++numJudges)
	totalScore += score[sid][numJudges];
if (numJudges != 0)
	average = totalScore / numJudges;

If you would like to get past the MAXMEMBERS and MAXJUDGES limits, it'd be recommended to use a vector . But since you can't, you have to use malloc , realloc or new , delete ; and pointers to manage and increase your memory use for these data.

basically I need the loop to stop when it hits -1. Rather than read the judges till the MAXJUDGES has been reached. she says call by reference not by value. you add a + to a variable in the function or something. See I need to setup an array that stores how many jdeges per student an I assume that controls how many it prints to screen. A judge counter array if you will. so the student with 5 judges and scores print 5 and ones with 4 print 4 rather than 8 every time.

basically I need the loop to stop when it hits -1. Rather than read the judges till the MAXJUDGES has been reached.

That has already been done in my previous post (look at the underlined portion):

int ReadScores (ifstream& fin)
{
	int i;
	for (i = 0; fin && i < MAXMEMBERS; ++i)
	{
		if (!(fin >> pianoPlayer[i]))
			break;
		if (!(fin >> profLevel[i]))
			break;
		if (!(fin >> weightFactor[i]))
			break;

		// Process the judges
		for (int j = 0; fin; ++j)
		{
			if (j >= MAXJUDGES)
			{
				// If the number of judges overflow the array size,
				// we have to clear off the remaining judge entries
				// so that we can continue reading from the next
				// player entry
				int k;
				if (!(fin >> k) || k == -1)
					break;
				else
					continue;
			}
			if (!(fin >> judgeNumber[i][j]) || [U]judgeNumber[i][j] == -1[/U])
				break;
			if (!(fin >> score[i][j]))
				break;
		}
	}
	return i;
}

she says call by reference not by value. you add a + to a variable in the function or something.

Call which method with parameters by reference or value? The ReadScores method above uses ifstream& fin as its parameter; the & tells the compiler that the parameter is passed in by reference and not by value.

See I need to setup an array that stores how many jdeges per student an I assume that controls how many it prints to screen. A judge counter array if you will. so the student with 5 judges and scores print 5 and ones with 4 print 4 rather than 8 every time.

That's already been done in my previous post too. You do not need another array to store the number of judges; all you need is to read the array until you either hit a -1 in the judgeNumber[sid][[I]n[/I]] , or hit MAXJUDGES , whichever comes first. The underlined portion in this excerpt of my previous post checks if we reached -1 yet:

int numJudges = 0;
double totalScore = 0;
double average = 0;
for (; numJudges < MAXJUDGES && [U]judgeNumber[sid][numJudges] != -1[/U]; ++numJudges)
	totalScore += score[sid][numJudges];
if (numJudges != 0)
	average = totalScore / numJudges;

It is still posting all eight judges regardless of the -1. Here is the code I am using.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
const int MAXMEMBERS = 20;
const int MAXJUDGES = 8;
int ReadScores(ifstream& fin);
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				int numPlayers);
int ProcessScores(ifstream& fin);
int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS][MAXJUDGES];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];
int judgeNumber[MAXMEMBERS][MAXJUDGES];
int category;  //category of music the students are playing
int judgeCount[MAXMEMBERS];
int numPlayers;
int i= 0;
int j= 0;
int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
	fout.open("Report.out");
	if (fout.fail())
	{
		cout << "Error: Output File";
		exit (1);
	}
ReadScores (fin);
ProcessScores (fin);
numPlayers = ReadScores (fin);
PrintReport(fout, pianoPlayer, score, numPlayers);
fin.close();
fout.close();
}

int ReadScores (ifstream& fin)
{
	int i;
	fin >> category;
	for (i = 0; fin && i < MAXMEMBERS; ++i)
	{
		if (!(fin >> pianoPlayer[i]))
			break;
		if (!(fin >> profLevel[i]))
			break;
		if (!(fin >> weightFactor[i]))
			break;

		// Process the judges
		for (int j = 0; fin; ++j)
		{
			if (j >= MAXJUDGES)
			{
				// If the number of judges overflow the array size,
				// we have to clear off the remaining judge entries
				// so that we can continue reading from the next
				// player entry
				int k;
				if (!(fin >> k) || k == -1)
					break;
				else
					continue;
			}
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
				break;
			if (!(fin >> score[i][j]))
				break;
		}
	}
	return i;
}
int ProcessScores(ifstream& fin)
{
	for (i = 0; i < MAXMEMBERS; i++)
	{
		
		averageRaw[i][j]= score[i][j] + sum;
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				 int numPlayers)
{
	for (i = 0; i < MAXMEMBERS; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		for (j =0; j < MAXJUDGES; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
	}	
	return;
}

Here is the Report.out

Piano Player: 6010
Judge Number: 23 Score: 7
Judge Number: 25 Score: 8.5
Judge Number: 34 Score: 7
Judge Number: 12 Score: 7.5
Judge Number: -1 Score: 0
Judge Number: 0 Score: 0
Judge Number: 0 Score: 0
Judge Number: 0 Score: 0
Piano Player: 6012
Judge Number: 23 Score: 7.5
Judge Number: 34 Score: 7
Judge Number: 45 Score: 7
Judge Number: 50 Score: 7.5
Judge Number: -1 Score: 0
Judge Number: 0 Score: 0
Judge Number: 0 Score: 0
Judge Number: 0 Score: 0

Is the problem in how i am outputting the results?

You need to have the underlined portion in your condition, as mentioned in my previous post:

void PrintReport(ofstream& fout)
{
	for (i = 0; i < MAXMEMBERS; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		for (j =0; j < MAXJUDGES [U]&& judgeNumber[i][j] != -1[/U]; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
	}	
	return;
}

You might also consider adding numPlayers to the condition of the outer loop, as underlined:

void PrintReport(ofstream& fout)
{
	for (i = 0; i < MAXMEMBERS [U]&& i <numPlayers[/U]; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		for (j =0; j < MAXJUDGES && judgeNumber[i][j] != -1; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
	}	
	return;
}

In fact, the numPlayers condition alone should suffice, being that numPlayers will not exceed MAXMEMBERS (underlined):

void PrintReport(ofstream& fout)
{
	for (i = 0; [U]i <numPlayers[/U]; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		for (j =0; j < MAXJUDGES && judgeNumber[i][j] != -1; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
	}	
	return;
}

I noticed that you are placing redundant variables (underlined) in your method declarations, which I cleared off in ReadScores, and now here in PrintReport:

void PrintReport(ofstream& fout, [U]int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES], int numPlayers[/U])

There is no need to do that because your arrays and numPlayers variables are all outside of any method declaration. This makes it globally available, which means any method in that .cpp file can access these variables (underlined):

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
[U]const int MAXMEMBERS = 20;
const int MAXJUDGES = 8;[/U]
int ReadScores(ifstream& fin);
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				int numPlayers);
int ProcessScores(ifstream& fin);
[U]int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS][MAXJUDGES];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];
int judgeNumber[MAXMEMBERS][MAXJUDGES];
int category;[/U]  //category of music the students are playing
[U]int judgeCount[MAXMEMBERS];
int numPlayers;
int i= 0;
int j= 0;[/U]
int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
...

By the way, looking at the source code you gave, that shouldn't compile at all. Your ProcessScores method is deformed. What's with that?

I copied it while in the middle of doing something. Kick ass I have prevented it from printing judges that dont exist. I am having problems with the average score thing. I need to average the score and then multiply it by the weight factor. From your post it doesnt seem like an aarray takes care of this. a 2-d array is supposed to handle the judges scores and weighted scores. How do i set that up. I did it like you pointed out and it kept on just shooting up 0. Also I am still reading beyong the number of players, instead i am reading until the max number I think. You are saving my ass by the way. Know I appreciate all this help. Here is what i did for the average score:

int ProcessScores(ifstream& fin)
{
	int numJudges;
	double weightedScore[i][j];
	double average[i];
	for (numJudges = 0; numJudges < MAXJUDGES && judgeNumber[i][j] != -1; ++numJudges)
	{
		totalScore[i][j] += score[i][j];
	}
	if (numJudges != 0)
	{
		average[i] = totalScore[i][j] / numJudges;
		i++;
	}
	return i;
}

You might want to add two more global array variables first, assuming you need the unweighted and weighted:

int average[MAXMEMBERS];
int weightedScore[MAXMEMBERS];

Then you can calculate for each value with three loops. I don't know but you seemed to have thrown things together without much thought or understanding.

Assuming you want to calculated the averages for each student:

void ProcessScores ()
{
	int numJudges;
	double totalScore;
	for (int i = 0; i < numPlayers; ++i)
	{
		for (numJudges = 0, totalScore = 0; numJudges < MAXJUDGES && judgeNumber[i][j] != -1; ++numJudges)
		{
			totalScore += score[i][numJudges];
		}
		if (numJudges != 0)
			average[i] = totalScore / numJudges;
		weightedScore[i] = average[i] * weightFactor[i];
	}
}

I've changed your return type to void since it doesn't make sense to return anything. Also, I removed the ifstream& parameter because it is not necessary either.

Oh yes, you should not declare int i and int j globally, because usually those are used specifically in methods for loop counts, and it would be bad if you forget to reset them to zero for a certain loop.

Hope this helps, and I'm glad that I was able to provide you with assistance. If you truly like what I've done for you, I'd appreciate a small donation of any amount (via PayPal); PM me if you are willing and I'll give you my e-mail. Thanks!

Ahhhh. You are given that there may be up to a maximum number of contesants and up to a certain number of judges, but there may be less than the maximum as well, so the arrays may be "partially filled". You are to use the maximum numbers to create your arrays at compile time. Since there may be less than the maximum number of contestants or less than the maximum number of judges you need to keep track of how many there actually are with a appropriate variables. The EOF will indicate end of input on the group of contestants and the -1 flag will end data on each individual contestant.

Declare:
array of int for contestant numbers
array of int for proficiency levels
array of double for difficulty level
array of int for number of judges for this contestant
array of double for average score for this contestant
an int to act as first available index available (will be used for all of the above arrays given they are parallel arrays)

However I still don't understand the instructions:
>>I need two dimensional arrays for the judge ids judges scores and weighted scores.

and how that fits with the two dimensional array as declared:

int judgeNumber[MAXMEMBERS][MAXJUDGES])

The above 2D array could be used to keep track of each judges raw score for each contestant and could be correlated with the five other arrays, but it doesn't include the judge id numbers or the weighted scores and even if it was the desired way to keep track of the raw scores each contestant received (without respect to which judge gave them each raw score), it would need to be type double, given the raw scores are doubles, not int.

As to the algorhythm, you should be able to use any of the control loops (for, while, do/while) to do what you want. Depending on the details you may be able to do everything with one reading of the file, or you may need to read it more than once.

//declare and initialize variables as needed before loops start

//outer loop controls when to stop reading from file
while there is room in the array(s) and there is input into a contestants ID 
{
    read in proficiency
    read in difficulty rating
    read in first judge number

    //inner loop controls how many judges scores there are per contestant
    while judge number not equal to -1 and judge count not at maximal level
        increment judge count
        read in judge score
        adjust raw score for difficulty rating
        add adjusted score to accumulated score
        read in next judge number

    //determine why inner loop stopped
    if inner loop stopped because judges id was -1
      // all scores for this contestant have been successfully read
      calculate average score
    else
      a problem was encountered so notify user and stop program
     
    some variables will need to reset for each new contestant
    increment index of the 5 arrays to indicate going on to next contestant
}

if EOF found
  //entire file read in
  stand up and cheer
else
  //something unexpected happened so notify user

When you write stuff to the appropriate array is up to you, though there are some spots that would be prefered. What you are to do with that multidimensional array is still beyond me though. Further explanation is necessary to determine how to weave it into the program as a learning execise.

Learn to write out whatever you can in very rough form before actually writing code. And progressively get it more and more code like with each iteration you write. After a while you can skip some of the routine steps and just focus on the bigger ideas, but it will improve your ability to write code if you can learn to write solutions without using code first.

All I need now is the array for the judge count. I have to have it. It isnt working correctly anyway. I need the counter controlled repitition to be controlled by the judge count array instead of MAXJUDGES because it keeps on printing judges that are not there. Also the weighted score and average do not work. they just spit out 0. It is also displaying all the way to MAXMEMBERS players. It wil have 4 or 5 with all zeros. I need to prevent this Here is the code. I would be glad to make a donation as I am sure this has been tryingg. Just let me get this finished first. I am on deadline and will fail this class otherwise. Go ahead and send me the email. Here is the code:

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
const int MAXMEMBERS = 20;
const int MAXJUDGES = 5;
int ReadScores(ifstream& fin);
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				int numPlayers);
void ProcessScores();
int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS][MAXJUDGES];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];
int judgeNumber[MAXMEMBERS][MAXJUDGES];
double average[MAXMEMBERS];
int weightedScore[MAXMEMBERS];
int category;  //category of music the students are playing
int judgeCount[MAXMEMBERS];
int numPlayers;

int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
	fout.open("Report.out");
	if (fout.fail())
	{
		cout << "Error: Output File";
		exit (1);
	}
ReadScores (fin);
ProcessScores ();
numPlayers = ReadScores (fin);
PrintReport(fout, pianoPlayer, score, numPlayers);
fin.close();
fout.close();
}

int ReadScores (ifstream& fin)
{
	int i= 0;
	int j= 0;
	fin >> category;
	for (i = 0; fin && i < MAXMEMBERS; ++i)
	{
		if (!(fin >> pianoPlayer[i]))
			break;
		if (!(fin >> profLevel[i]))
			break;
		if (!(fin >> weightFactor[i]))
			break;

		// Process the judges
		for (int j = 0; fin; ++j)
		{
			if (j >= MAXJUDGES)
			{
				// If the number of judges overflow the array size,
				// we have to clear off the remaining judge entries
				// so that we can continue reading from the next
				// player entry
				int k;
				if (!(fin >> k) || k == -1)
					break;
				else
					continue;
			}
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
				break;
			if (!(fin >> score[i][j]))
				break;
		}
	}
	return i;
}
void ProcessScores ()
{
	int i = 0, j=0;	
	int numJudges;
	double totalScore;
	for (int i = 0; i < numPlayers; i++)
	{
		for (numJudges = 0, totalScore = 0; numJudges < MAXJUDGES && judgeNumber[i][j] != -1; ++numJudges)
		{
			totalScore += score[i][numJudges];
		}
		if (numJudges != 0)
			average[i] = totalScore / numJudges;
		weightedScore[i] = average[i] * weightFactor[i];
	}
}

void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				 int numPlayers)
{
	int i=0, j=0;
	for (i = 0; i < MAXMEMBERS; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		for (j =0; j < MAXJUDGES; j++)
		{
			fout << "Judge Number: " << judgeNumber[i][j] << "   ";
			fout << "Score: " << score[i][j] << "\n";
		}
		fout << "Average Score: " << average[i] << "\n";
		fout << "Weighted Score: " << weightedScore[i] << "\n";
	}	
	return;
}

I think in the print report function is the problem. It prints until maxmembers regardless as well as for maxjudges. that is why i think i need that other array to say < judgeCountArray

You want to print out only to numplayers, not MaxPlayers. Likewise you only want to print out to the judgeCount for the appropriate player, not MaxJudges. Use the values stored in the appropriate array(s) with the appropriate index to get what you need/want.

Ok Lerner thanks. I fixed the problem with the players, but it is still reading in 7 judges per player. The problem is in the array. Here is the code to fill the array:

if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
					break;
void ProcessScores ()
{
	int i = 0, j=0;	
	
	double totalScore;
	for (int i = 0; i < numPlayers; i++)
	{
		for (numJudges = 0, totalScore = 0; numJudges < MAXJUDGES && judgeNumber[i][j] != -1; numJudges++)
		{
			totalScore += score[i][numJudges];
		}
		if (numJudges != 0)
			average[i] = totalScore / numJudges;
		weightedScore[i] = average[i] * weightFactor[i];
	}
}

It is not stopping at the -1 it just reads until MAXJUDGES, so if i put in the PrintReport print until numJudges it does the 7 anyway. This also messus up my calculations because some scores end up being 0. Also I need the weighted score to be in 2d array for every score to be weighted not just the average.

numJudges < MAXJUDGES

This is wrong. You want the number of judges giving scores for player with index of i. Think, where did you calculate that value and where did you---HINT-or should you--- have stored that value and how would you access it? Learning how to manipulate values in arrays is undoubtedly part of the learning process here so I don't want to give too many clues. If you understand what you are doing in ReadScores() and why the instructor wanted you to develop all 5 of the parallel arrays you'll figure it out.

I have finished for the most part. I tried to pull out the formatting of the scores into a printjudges function, but it alway prints 4 judges. I cannot figure out why. Any ideas on how to seperate this into a seperate function:

f

out << "           ";
		for (j =0; j < judgeCount[i]; j++)
		{		
			fout << "Judge";
			fout.width(10);	
		}
		fout << "\n         ";
		for (j =0; j < judgeCount[i]; j++)
		{
			fout.width(7);
			fout << judgeNumber[i][j] << "   ";	
		}
		fout << "\n     -----------------------------------------------------------------------\n";
		fout << "         ";

Also the average I am getting is wrong I will repost the whole file as to not leave out anything. Everything else seems to be working fine. I have to put a selection sort, but I am hoping my notes help me through that.

#include <iostream>
#include <fstream>
#include <cstdlib>

using namespace std;
const int MAXMEMBERS = 20;
const int MAXJUDGES = 7;
void SetFormat (ofstream& fout);
void Header(ofstream& fout);
int ReadScores(ifstream& fin);
void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				int numPlayers);
void ProcessScores();
void SwitchProfLevel(ofstream& fout);
void SwitchCategory(ofstream& fout);
int pianoPlayer[MAXMEMBERS];
double score[MAXMEMBERS][MAXJUDGES];
double weightFactor[MAXMEMBERS];
int profLevel[MAXMEMBERS];
int judgeNumber[MAXMEMBERS][MAXJUDGES];
double average[MAXMEMBERS];
double weightedScore[MAXMEMBERS][MAXJUDGES];
int category;  //category of music the students are playing
int judgeCount[MAXMEMBERS];
int numPlayers;

int numJudges;
int main()
{
	ifstream fin;
	ofstream fout;

	fin.open("PianoREV.data");
	if (fin.fail())
	{
		cout << "Error: Input File";
		exit (1);
	}
	fout.open("Report.out");
	if (fout.fail())
	{
		cout << "Error: Output File";
		exit (1);
	}
	SetFormat(fout);
	ReadScores (fin);
	ProcessScores ();
	PrintReport(fout, pianoPlayer, score, numPlayers);
	fin.close();
	fout.close();
	return 0;
}
/************************************************************************************************/
/* Function Name: SetFormat									*/
/* Function Purpose: Setup formatting of fout							*/
/* Input Parameters: none									*/
/* Return value: none										*/
/************************************************************************************************/
void SetFormat (ofstream& fout)
{
	fout.setf(ios::fixed);
	fout.setf(ios::showpoint);
	fout.precision(1);
	return;
}  //end Set Format

/************************************************************************************************/
/* Function Name: Header									*/
/* Function Purpose: Output the header of file							*/
/* Input Parameters: none									*/
/* Return value: none										*/
/************************************************************************************************/
void Header (ofstream& fout)
{
	// output header to file
	fout << "    \n\n	Federation of Music Teachers\n";
	fout << " Mardi Gras Piano Invitational Competition\n";
	fout << "	 Baton Rouge, Louisiana\n";
	return;
} //end Header
int ReadScores (ifstream& fin)
{
	int i= 0;
	int j= 0;
	fin >> category;
	while(fin >> pianoPlayer[i])
	{
		if (!(fin >> profLevel[i]))
			break;
		if (!(fin >> weightFactor[i]))
			break;

		// Process the judges
		for (int j = 0; fin; j++)
		{
			
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
					break;
			if (!(fin >> score[i][j]))
				break;
			judgeCount[i] = j+1;
		}
		i++;
		numPlayers++;
	}
	return i;
}
void ProcessScores ()
{
	int i = 0, j=0;	
	
	double totalScore;
	for (int i = 0; i < numPlayers; i++)
	{
		for (j = 0; j <= judgeCount[i]; j++)
		{
			weightedScore[i][j] = score[i][j] * weightFactor[i];
		}
		for (numJudges = 0, totalScore = 0; numJudges <= judgeCount[i] && judgeNumber[i][j] != -1; numJudges++)
		{
			totalScore += weightedScore[i][numJudges];
		}
		
		average[i] = totalScore / numJudges;
	}
}
void SwitchProfLevel(ofstream& fout)
{
	int i = 0;
	switch (profLevel[i])
	{
		case 1:
			fout << " Primary\n";
			break;
		case 2:
			fout << " Intermediate\n";
			break;
		case 3: 
			fout << " Advanced Intermediate\n";
			break;
		case 4:
			fout << " Senior\n";
			break;
		default:
			cout << " Invalid Proficiency Level\n";
			break;
	}
}
void SwitchCatType(ofstream& fout)
{
	switch (category)
	{
		case 1:
			fout << " Ballad\n";
			break;
		case 2:
			fout << " Concerto\n";
			break;
		case 3: 
			fout << " Modern\n";
			break;
		case 4:
			fout << " Sonata\n";
			break;
		case 5: 
			fout << " Waltz\n";
			break;
		default:
			cout << " Invalid Category\n";
			break;
	}
}

void PrintReport(ofstream& fout, int pianoPlayer[MAXMEMBERS], double score[MAXMEMBERS][MAXJUDGES],
				 int numPlayers)
{
	int i=0, j=0;
	for (i = 0; i < numPlayers; i++)
	{
		fout << "Piano Player: ";
		fout << pianoPlayer[i] << "\n";
		fout << "Category:";
		SwitchCatType(fout);
		fout << "Proficiency Level:";
		SwitchProfLevel(fout);
		fout << "           ";
		for (j =0; j < judgeCount[i]; j++)
		{		
			fout << "Judge";
			fout.width(10);	
		}
		fout << "\n         ";
		for (j =0; j < judgeCount[i]; j++)
		{
			fout.width(7);
			fout << judgeNumber[i][j] << "   ";	
		}
		fout << "\n     -----------------------------------------------------------------------\n";
		fout << "         ";		
		for (j =0; j < judgeCount[i]; j++)
		{
			fout.width(7);
			fout << score[i][j] << "   ";
		}
		fout << "\n         ";
		for (j =0; j < judgeCount[i]; j++)
		{
			fout.width(7);
			fout << weightedScore[i][j] << "   ";
		}
		fout << "\nWeight: " << weightFactor[i];
		fout << "\nAverage Score: " << average[i] << "\n\n\n";
	}	
	return;
}

I also am having problem with the switch statement I set up. It is staying on the same i. How do I pass that variable to other functions. I am also completely lost on the selection sort. My notes suck and do not work. I also need help changing this part of function. I changed the other two , but cannot seem to get while loop to work. I need to not use this complicated method, but the method used before it to read in.

while(fin >> pianoPlayer[i])
	{
		fin >> profLevel[i];
		fin >> weightFactor[i];
		for (int j = 0; fin; j++)
		{
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
					break;
			if (!(fin >> score[i][j]))
				break;
			judgeCount[i] = j+1;
		}
		i++;
		numPlayers++;
	}
	return i;

Do you know for sure that some contestant has something other than 4 scores?

If so here's are some thoughts.

Here's how you count the number of judges, which I think is correct

for (int j = 0; fin; j++)
judgeCount = j+1;

But here is how you use it in ProcessScores():

for (j = 0; j <= judgeCount; j++)
weightedScore[j] = score[j] * weightFactor;

I think the problem here is the operator you are using in the terminating condition. Say judgeCount == 2 meaning for player there were 2 judges scoring player so you want to add both scores to get the average. However j in the second snippet would range from 0 to 2 meaning the loop would run 3 times instead of 2 and since score[2] is junk (there were only 2 judges so there are only two scores and [2] means the third score which is who knows what) something bad is likely to happen. It may shut down the program, it may use a made up value, who knows. You don't want to use operator <= in the terminating condition, you want a different operator (in both places. HINT---You do it correctly in PrintScores()).

If you make that correction then numJudges below is going to be off.

average = totalScore / numJudges;

However, you know the number of judges who judged player, it's judgeCount. Why not use it again rather than relying on the result of some loop counter?

Maybe these corrections will be all there is, I can't say for sure, but make them and see what happens.

Here is what I changed it to. It still does not work. It is totally off I dont know where it is coming up with the numbers.

void ProcessScores ()
{
	int i = 0, j=0;	
	
	double totalScore;
	// recieve scores and process. find weighted score and average
	for (int i = 0; i < numPlayers; i++)
	{
		for (j = 0; j < judgeCount[i]; j++)
		{
			weightedScore[i][j] = score[i][j] * weightFactor[i];
			
		}	
		totalScore += weightedScore[i][numJudges];
		
		average[i] = totalScore / judgeCount[i];
	}
}

Also can you help me convert this into terms that i know. I dont understand the if!( blah

for (int j = 0; fin; j++)
		{
			if (!(fin >> judgeNumber[i][j]) || judgeNumber[i][j] == -1)
					break;
			if (!(fin >> score[i][j]))
				break;
			//set judgecount to j +1 because there cannot be 0 judges
			judgeCount[i] = j+1;
		}

Any idea on how to do a selection sort.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.