Sorry guys, this is a huge chunk of code that looks inefficient as f***. This was for a class I had last spring, so I'm not rying to cheat I just want an answer. So here's the assignment,

Develop an object-oriented program to produce a grade report and an error report for a history teacher of a course named “HIST220”. Your task is to produce the reports with the following information in mind:
Assume that the data file for this program contains no more than 100 records. Each record consists of five exam scores in the range of 0-100.
Input record format:
Student-ID-Number, Exam1-Score, Exam2-Score, Exam3-Score, Exam4-Score, Exam5-Score
Compute the average and the letter grade for each student. The instructor has decided to drop the lowest of the five scores. Compute also the average and the letter grade based on the top four exam scores. Include these four pieces of information and the other six pieces of information from data file in your report (a total of ten values).
Use the following grading scales when computing the letter grades (A = 90%, B = 80%, C = 70%, D = 60%, F = 0%).
Data Validation: If the id or any of the scores is not valid then send that record to an error file. The error file should contain only the bad/invalid records with an appropriate main report heading and column. The records in the error file should be numbered (1, 2, 3 and so on).
Each detail line in the main report should include the following items (all 10 fields on one line).
Student-ID-Number, Exam1-Score*, Exam2-Score*, Exam3-Score*, Exam4-Score*, Exam5-Score*, Average Of 5 Scores, Letter grade, Average Of Top 4 Scores, New Letter Grade
Each detail line should contain only one asterisk (*). It should be placed next to the smallest score for a give student.
When defining the class for this program, make sure to have, among other member functions, a member function for each of the following tasks:
Read in a record
Print a record
Compute the average (based on five scores)
Compute the new average (based on the top four scores)
Compute the letter grade
A setter to assign six values (input record) to the corresponding member variables

Input record format:
Student-ID-Number, Exam1-Score, Exam2-Score, Exam3-Score, Exam4-Score, Exam5-Score
Output record format:
Student-ID-Number, Exam1-Score*, Exam2-Score*, Exam3-Score*, Exam4-Score*, Exam5-Score*, Average Of 5 Scores, Letter grade, Average Of Top 4 Scores, New Letter Grade
Store the following student records in a file and later read the data from it.

222300      90  90  80  90  90
333400      100 88  87  93  90
444444      200 90  90  90  85
555600      80  80  80  80  72
666666      90  90  -90 90  92
666700      77  77  77  66  77
777800      70  68  66  64  62
8888888     88  99  87  66  90
888900      80  0   0   60  70

I wanted to use a class array, and then an array for grades. I asked my teacher for help, but he just kept saying "what do you think you should do". I couldn't figure out how to create a default construtor for the class array, or the grade array. I asked my teacher again and again he said "what do you think you should do" I got angry and said forget it, if he's not gonna help I'm not gonna stress over it. here is the code I came up with because it's all I know how to do. So here's my code

//Project: Program3

    //Date: 5/20/2013

    //This program takes the student id and five exam scores from a file. It then
    //finds the average grade of the five exam scores. Then it drops the lowest
    //score and recalculates the average of four exam scores.


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

    int const NUMBEROFSUDENTS = 100;

    class student
    {

      public:
        void setGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
        int getGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[]);
        void error(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
        void average(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
         double total[], int count);
        void newAverage(double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int newAverage[], int count);
        void grade(int studentId[], int newAverage[], char grade[], int count);
        void print(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
          double total[], int newAverage[], char grade[], int count);
        student(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
        student();

      private:
        int id[NUMBEROFSUDENTS];
        double first[NUMBEROFSUDENTS];
        double second[NUMBEROFSUDENTS];
        double third[NUMBEROFSUDENTS];
        double fourth[NUMBEROFSUDENTS];
        double fifth[NUMBEROFSUDENTS];

    };



    int main()
    {

      int studentId[NUMBEROFSUDENTS];
      double exam1[NUMBEROFSUDENTS];
      double exam2[NUMBEROFSUDENTS];
      double exam3[NUMBEROFSUDENTS];
      double exam4[NUMBEROFSUDENTS];
      double exam5[NUMBEROFSUDENTS];
      double total[NUMBEROFSUDENTS];
      int newAverage[NUMBEROFSUDENTS];
      char grade[NUMBEROFSUDENTS];
      int count = 0;

      student firstStudent;
      firstStudent.setGrades(studentId, exam1, exam2, exam3, exam4, exam5, count);
      count = firstStudent.getGrades(studentId, exam1, exam2, exam3, exam4, exam5);
      firstStudent.error(studentId, exam1, exam2, exam3, exam4, exam5, count);
      firstStudent.average(studentId, exam1, exam2, exam3, exam4, exam5, total, count);
      firstStudent.newAverage(exam1, exam2, exam3, exam4, exam5, newAverage, count);
      firstStudent.grade(studentId, newAverage, grade, count);
      firstStudent.print(studentId, exam1, exam2, exam3, exam4, exam5, total, newAverage, grade, count);


    }
    //default constructor
    student::student()
    {
      for (int i = 0; i <= 9; i++)
      {
        id[i] = 0;
        first[i] = 0;
        second[i] = 0;
        third[i] = 0;
        fourth[i] = 0;
        fifth[i] = 0;
      }
    }

    student::student(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count)
    {

      setGrades(studentId, exam1, exam2, exam3, exam4, exam5, count);

    }
    //gets grade from fie and puts student id and exams into arrays
    int student::getGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[])
    {
      ifstream inFile;
      inFile.open("student.txt");

      int count = 0;

        while (inFile.peek() !=EOF)
        {
          inFile >> studentId[count] >> exam1[count] >> exam2[count] >> exam3[count] >> exam4[count] >> exam5[count];
          count++;

        }

      inFile.close();

      return count;

    }
    //looks through student id to see if number are within range
    //looks at exam scores and check if they are between 0 and 100
    void student::error(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count)
    {
      ofstream outFile;
      outFile.open("error.txt");

      int idError[NUMBEROFSUDENTS];
      int examError[NUMBEROFSUDENTS];

      for (int i = 0; i <=count; i++)
      {
        if (0 > studentId[i] || studentId[i] > 1000000)
        {
          idError[i] = studentId[i];
          outFile << "student id error: " << idError[i] << endl;
        }

        if (0 > exam1[i] || exam1[i] > 100)
        {
          examError[i] = exam1[i];
          outFile << "exam error: " << examError[i] << endl;
        }

        if (0 > exam2[i] || exam2[i] > 100)
        {
          examError[i] = exam2[i];
          outFile << "exam error: " << examError[i] << endl;
        }

        if (0 > exam3[i] || exam3[i] > 100)
        {
          examError[i] = exam1[i];
          outFile << "exam error: " << examError[i] << endl;
        }

        if (0 > exam4[i] || exam4[i] > 100)
        {
          examError[i] = exam1[i];
          outFile << "exam error: " << examError[i] << endl;
        }

        if (0 > exam5[i] || exam5[i] > 100)
        {
          examError[i] = exam1[i];
          outFile << "exam error: " << examError[i] << endl;
        }
      }
        outFile.close();
    }
    //sets student ids and exams
    void student::setGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count)
    {

      for (int i = 1; i < count; i++)
      {
      studentId[i] = id[i];
      exam1[i] = first[i];
      exam2[i] = second[i];
      exam3[i] = third[i];
      exam4[i] = fourth[i];
      exam5[i] = fifth[i];

      }
    }
    //calculates average of five exam scores
    void student::average(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
     double total[], int count)
    {

      for (int i = 1; i < count; i++)
      {
        total[i] = exam1[i] + exam2[i] + exam3[i] + exam4[i] + exam5[i];
      }

    }
    //calculates average of new exam score after lowest grade has been dropped
    void student::newAverage(double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
      int newAverage[], int count)
    {
      double lowest[9];
      double total[9];

      for (int i = 1; i < count; i++)
      {

          lowest[i] = exam1[i];
          if(exam1[i] < lowest[i])
              lowest[i] = exam2[i];
          if(exam3[i] < lowest[i])
              lowest[i] = exam2[i];
          if(exam4[i] < lowest[i])
              lowest[i] = exam4[i];
          if(exam5[i] < lowest[i])
              lowest[i] = exam5[i];

          total[i] = exam1[i] + exam2[i] + exam3[i] + exam4[i] + exam5[i];

          newAverage[i] =  (total[i] - lowest[i]) / 4;

      }
    }
    //finds letter grade for exam average
    void student::grade(int studentId[], int newAverage[], char grade[], int count)
    {

      for (int i = 1; i < count; i++)
      {
        if (newAverage[i] >= 90)
        grade[i] = 'A';
      else if (newAverage[i] >= 80)
        grade[i] = 'B';
      else if (newAverage[i] >= 70)
        grade[i] = 'C';
      else if (newAverage[i] >= 60)
        grade[i] = 'D';
      else
        grade[i] = 'F';

      }
    }
    //prints student id, exams, old exam score, new exam score, and grades
    void student::print(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
      double total[], int newAverage[], char grade[], int count)
    {

      ofstream outFile;
      outFile.open("report.txt");

      for (int i = 1; i < count-1; i++)
      {
      outFile << setw(10) << left << "Student Id: " << setw(9) << left << studentId[i] << " ";
      outFile << setw(7) << left << "Exam 1: " << setw(5) << left << exam1[i] << " ";
      outFile << setw(7) << left << "Exam 2: " << setw(5) << left << exam2[i] << " ";
      outFile << setw(7) << left << "Exam 3: " << setw(5) << left << exam3[i] << " ";
      outFile << setw(7) << left << "Exam 4: " << setw(5) << left << exam4[i] << " ";
      outFile << setw(7) << left << "Exam 5: " << setw(5) << left << exam5[i] << " ";
      outFile << setw(13) << left << "Total Score: " << setw(5) << left << total[i] << " ";
      outFile << setw(16) << left << "Adjusted Score: " << setw(5) << left << newAverage[i] << " ";
      outFile << setw(7) << left << "Grade: " << setw(3) << left << grade[i] << endl;

      }

      outFile.close();

    }

This will drive me nuts. I learned nothing in that class, because any quesiton we had he would say "what do you think". Any help would be greatly appreciated. Sorry for the length.

Firstly, to clean up your code you should use a multidimensional array... I assume you know that arrays are basically a way to prevent you from doing this (at least statically allocated ones):

int var1;
int var2;
int var3;

Instead they allow you to cobine those variables into:

int var[3];

Now look at your code. This is a section of it:

double exam1[NUMBEROFSUDENTS];
double exam2[NUMBEROFSUDENTS];
double exam3[NUMBEROFSUDENTS];
double exam4[NUMBEROFSUDENTS];
double exam5[NUMBEROFSUDENTS];

Look familiar? The solution to this is to make an array of arrays:

double exam[NUMBEROFSTUDENTS][5];

That solves your problem with the uglyness of your code. Now onto the problem of it not being right. I feel like you are not fully understanding how classes work. The whole point to a class is so that you don't have to send it all those arguments for all of its functions. Instead you can store them inside the class and then the compiler basically passes them for you! This means that this whole section is just wrong:

class student
{
public:
void setGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
int getGrades(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[]);
void error(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
void average(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
double total[], int count);
void newAverage(double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int newAverage[], int count);
void grade(int studentId[], int newAverage[], char grade[], int count);
void print(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[],
double total[], int newAverage[], char grade[], int count);
student(int studentId[], double exam1[], double exam2[], double exam3[], double exam4[], double exam5[], int count);
student();
private:
int id[NUMBEROFSUDENTS];
double first[NUMBEROFSUDENTS];
double second[NUMBEROFSUDENTS];
double third[NUMBEROFSUDENTS];
double fourth[NUMBEROFSUDENTS];
double fifth[NUMBEROFSUDENTS];
};

You are not storing a student with that. You are storing ALL the students! DO NOT DO THAT!!! Instead write the student class so that it is just one student. That is what classes are for! You can then make an array of students later! Therefore this is a better definition for your class (I am going to use NUMEXAMS instead of 5):

class Student //typical conventions are to capitalize class names, but its not standardized so its okay if you don't
{ //private: (Private is the default for a class in c++)
    int id;
    double exam[NUMEXAMS];
    public:
    //constructors:
    Student();//default
    Student(int id,//this is only 1 student, so only 1 id
            double exam[NUMEXAMS]);//again, since there is only 1 student, you wont need count or anything!
    //functions:
    bool error();//SIMPLE! returns true if there is an error, false otherwise!
    double average();//again, since all of your exams are stored INSIDE the class this is okay!
    double newAverage();
    char grade();
    void print();
    int getId();
    Student &setId(int id);
    void getMarks(double exam[]);//guaranteed to have length NUMEXAMS
    Student &setMarks(double exam[NUMEXAMS]);
};

Now since I am nice I will give you a couple examples. I will show you first how you would implement the average() function:

double Student::average()//note this can be made more efficient if you know NUMEXAMS in advance. Do you see how?
{
    int sum=0;
    for (int i=0; i<NUMEXAMS; ++i)
        sum+=exam[i];
    return (double)sum/NUMEXAMS;//you have to cast to double so that it will do floating point division instead of integer division.
}

And here is how you could construct your main function (it is missing some stuff, but it makes its point):

int main()
{
    int ids[NUMBEROFSTUDENTS];
    double exams[NUMBEROFSTUDENTS][NUMEXAMS];//you missed a 'T' in STUDENTS!
    int maxStudents;//so that we know if less than 100 students were entered
    //somehow input data
    Student *students=new Student[maxStudents];//default constructor will be called!
    for (int i=0; i<maxStudents; ++i)
        students[i].setId(ids[i]).setMarks(exams[i]);
    //output either by calling print or manually
}

Now you just need to fill in the rest of the functions. Good Luck!

Summary:

You are not using classes correctly. They are supposed to be used to modularize your code. It doesnt help if you shove all of your code into them. What you were doing was basically the class version of this:

int myMain()
{
    //everything I was going to do in main is now modularized! I'm cool right?!
}
int main()
{
    return myMain();
}

If you can't see how silly that is then you obviously haven't learnt enough about programming to be attempting this program.

Edited 3 Years Ago by Labdabeta

THIS!! THIS is what I wanted to do! I knew I wasnt using classes correclty because I could take everything in my class and put it in main and it would pretty much work the same. You have no idea how frustrating it is to know what you want to do but not be given any direction. I knew it was wrong the whole time I was doing and looked online and asked my teacher with no help. What's worse is I received a 100% on this project. I thought I at least would get a low grade and then HE would explain what I did wrong. Thanks Labdabeta I appreciate this more than you know!

I don't understand this Student *students=new Student[maxStudents]; class Student makes a new class up to [maxStudents] then quits?

mc3330418's question was that you allocated (dynamically) a Student object but missed (or failed) to deallocate them when your program exits.

Basically when you dynamically allocate an array the compiler calls the constructor for each object you want to allocate.

Yes, that's true, IF, you allocated them using the new statement. And its destructor will also be called ONLY when you use the delete statement. But if you mean by that that the compiler itself will deallocate for you that memory object then you are wrong. The compiler will not know how you allocated a memory and thus can never know how to deallocate them. The link you had given clearly speaks for that.

This question has already been answered. Start a new discussion instead.