Hi, sorry I'm posting so much all off a sudden, but I recently found these forums, and they've been a lot of help.

I'm have to read into the program from a file and output into another file. The problem is in function calculateGrade. When I output, I get a crazy symbol. I know the problem is in the loop. Can anybody help?

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;


const int noOfStudent=20;

struct studentType
{
	string studentFName;
	string studentLName;
	int testScore;
	char grade;
};

void getData (ifstream& inFile, studentType sList[], int listSize);
void calculateGrade (ifstream& inFile, studentType sList[], int listSize);
int highestScore (const studentType sList[], int listSize);
void printResult (ofstream& outFile, const studentType sList[], int listSize);


int main()
{
	ifstream inData;
	ofstream outData;
	studentType studentList[noOfStudent];

	inData.open("F:\\Ch11_Ex01Data.txt");
	if (!inData)
	{
		cout<<"The input file does not exist. Program terminates!"<<endl;
		return 1;
	}

	outData.open("F:\\Ch11_Ex01out.txt");
	if (!outData)
	{
		cout<<"Cannot open the output file. Program terminates!"<<endl;
		return 1;
	}

	getData(inData, studentList, noOfStudent);
	calculateGrade(inData, studentList, noOfStudent);
	printResult(outData, studentList, noOfStudent);

	return 0;
}


void getData(ifstream& inFile, studentType sList[], int listSize)
{
    string studentFName;
	string studentLName;
	int testScore;
	int i;
	
	for (i=0; i<listSize; i++)
	{
		inFile>>sList[i].studentFName>>sList[i].studentLName>>sList[i].testScore;
	}

}


void calculateGrade(ifstream& inFile, studentType sList[], int listSize)
{
	
	char grade;
	int testScore, i;
	
	for (i=0; i<listSize; i++)
	{
		inFile>>sList[i].testScore;
	

	if (testScore<=100 && testScore>=90)
	{
		grade = 'A';
	}
	else if (testScore<=89 && testScore>=80)
	{
		grade = 'B';
	}
	else if (testScore<=79 && testScore>=70)
	{
		grade = 'C';
	}
	else if (testScore<=69 && testScore>=60)
	{
		grade = 'D';
	}
	else
	{
		grade = 'F';
	}
	}


	
}


int highestScore(const studentType sList[], int listSize)
{
	int hScore=sList[0].testScore;






	return hScore;
}


void printResult(ofstream& outFile, const studentType sList[], int listSize)
{
	string studentFName;
	string studentLName;
	int maxScore= highestScore(sList, listSize);
	int i, testScore;
	char grade;


	outFile << setw(15) << "Student Name        "
		        << setw(14) << "Test Score"
				<< setw(7) << "Grade" << endl<<endl;

	for (i=0; i<listSize; i++)
	{
		outFile<<setw(10)<<left<<sList[i].studentLName<<left<<", "<<setw(15)<<left<<sList[i].studentFName
			   <<" "<<setw(10)<<left<<maxScore<<setw(7)<<grade<<endl;
	}


}

Recommended Answers

All 6 Replies

You never initialize grade to anything. In calculateGrade you assign to grade, but don't do anything else with it, so when the function terminates, all of the work is lost. Then in printResult, you redefine grade, but don't give it a value, so you'll get garbage.

I'm not quite sure I understand. Will it help if I change claculateGrade from void to char and then pass grade to functino printResult?

Yes, it would help. Quite a bit. :)

ok, so this is the new code....

#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
using namespace std;


const int noOfStudent=20;

struct studentType
{
	string studentFName;
	string studentLName;
	int testScore;
	char grade;
};

void getData (ifstream& inFile, studentType sList[], int listSize);
char calculateGrade (studentType sList[], int listSize);
int highestScore (const studentType sList[], int listSize);
void printResult (ofstream& outFile, studentType sList[], int listSize);


int main()
{
	ifstream inData;
	ofstream outData;
	studentType studentList[noOfStudent];

	inData.open("F:\\Ch11_Ex01Data.txt");
	if (!inData)
	{
		cout<<"The input file does not exist. Program terminates!"<<endl;
		return 1;
	}

	outData.open("F:\\Ch11_Ex01out.txt");
	if (!outData)
	{
		cout<<"Cannot open the output file. Program terminates!"<<endl;
		return 1;
	}

	getData(inData, studentList, noOfStudent);
	calculateGrade(studentList, noOfStudent);
	printResult(outData, studentList, noOfStudent);

	return 0;
}


void getData(ifstream& inFile, studentType sList[], int listSize)
{
    string studentFName;
	string studentLName;
	int testScore;
	int i;
	
	for (i=0; i<listSize; i++)
	{
		inFile>>sList[i].studentFName>>sList[i].studentLName>>sList[i].testScore;
	}

}


char calculateGrade(studentType sList[], int listSize)
{
	
	char grade;
	int testScore, i;

	
	for (i=0; i<listSize; i++)
	{
		sList[i].testScore;
	}
	

	if (testScore<=100 && testScore>=90)
	{
		grade = 'A';
	}
	else if (testScore<=89 && testScore>=80)
	{
		grade = 'B';
	}
	else if (testScore<=79 && testScore>=70)
	{
		grade = 'C';
	}
	else if (testScore<=69 && testScore>=60)
	{
		grade = 'D';
	}
	else
	{
		grade = 'F';
	}
	
	return grade;


	
}


int highestScore(const studentType sList[], int listSize)
{
	int hScore=sList[0].testScore;






	return hScore;
}


void printResult(ofstream& outFile, studentType sList[], int listSize)
{
	string studentFName;
	string studentLName;
	int maxScore= highestScore(sList, listSize);
	int i, testScore;
	char grade;

	grade=calculateGrade(sList, listSize);

    
	outFile << setw(15) << "Student Name        "
		        << setw(14) << "Test Score"
				<< setw(7) << "Grade" << endl<<endl;

	for (i=0; i<listSize; i++)
	{
		outFile<<setw(10)<<left<<sList[i].studentLName<<left<<", "<<setw(15)<<left<<sList[i].studentFName
			   <<" "<<setw(10)<<left<<maxScore<<setw(7)<<grade<<endl;
	}


}

That got the program to print out letters, however, it's printing F's for everbody, and they shouldn't be. Also, can anybody give me clue as to how to start the function highestScore? Do I use a 2d array type of set up?

You have the same problem with testScore. You define it, don't initialize it, but still use it in your tests. Technically, the program is allowed to crash noisily because you're accessing uninitialized memory, but undefined behavior in your case is getting to the else clause and setting grade to 'F' in every case.

Finding the highest score is a cakewalk if you use the standard library:

bool gradeLess(const studentType& a, const studentType& b)
{
  return a.grade < b.grade;
}

int highestScore (const studentType sList[], int listSize)
{
  return max_element(sList, sList + listSize, gradeLess)->grade;
}

Otherwise you'll be stuck doing it manually:

int highestScore (const studentType sList[], int listSize)
{
  int max = sList[0].grade;

  for (int i = 0; i < listSize; i++) {
    if (sList[i].grade > max)
      max = sList[i].grade;
  }

  return max;
}

Thanks Dogtree, you've been an awesome help!

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.