Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

The program will print a grade report for students in a course. Input: An instru

ID: 3638970 • Letter: T

Question

The program will print a grade report for students in a course.

Input:
An instructor has a class of no more than 40 students each of whom takes 6 tests. For
each student in the class, there is one line in the input file. The line contains the student's first name (no more than 10 characters), last name (no more than 12 characters), ID# (a string of 6 characters) and 6 integer test scores. File student_input.dat included with the assignment is fine for testing.

Example of file input:

Adam Zeller 45231 78 86 91 64 90 76
Barbara Young 274253 88 77 91 66 82 93
Carl Wilson 11223 87 77 76 78 77 82

Note that a different file will be used for testing. Also note that amount of blank spaces between names, ID, and grades can be arbitrary, i.e., any number. Total amount of characters for each line will not exceed 256.

Processing:
The program is to read the input file and calculate each student's average and letter
grade for the course. The average is calculated by dropping the student's lowest test score and
then averaging the remaining 5 scores. In addition, the number of students receiving each letter
grade (A, B, C, D, or F ) for the course is to be calculated. The cutoff for the letter grades is 89.5 for an A, 79.5 for a B, 69.5 for a C, 59.5 for a D.

Output:
The program is to print to an output file (student_results.dat) a table showing each
student's name (Last, First), identification number, course average (rounded to 1 decimal place),
and letter grade. Following the last student, a summary of the number of students receiving each letter grade is to be printed. All output should be clearly labeled and easy to read. The output file should have a meaningful heading at the top of the file.

Example of file output:

Last_name First_name ID Average_Score Grade

Zeller Adam 45231 82.3 B

NOTES:
• The program must be modular, with significant work done by functions. Each function should perform a single, well-defined task. When possible, create re-usable functions. Do not write trivial functions such as a function to read a single value from an input file.

• You must have at least three functions: One that drops the lowers grade, one that calculates the average, and one that converts the average to the letter grade.

IMPORTANT
• Use character arrays and c-strings (#include <cstring>) for converting text to integers. You
cannot use string objects and any methods that are included in string.h library, i.e, you cannot
use #include <string> in your code. Otherwise you are going to be penalized.
• You program must detect and correct following problems in the input file
o Negative grade present – display an error and terminate the program
o Less than 6 grades exist (minimum of 5 will be provided) – display a warning in
the console, but continue the execution of the program. Calculate the average and the letter grade based on the existing grades, but in this case do not discard the
lowest grade

NOTE: PLEASE USE SOME POINTERS.
DO NOT USE "CLASS"(A class is an expanded concept of a data structure)

Explanation / Answer

test with other input lines and check the output yourself.

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

const int LINE_BUFF_SIZE = 256 + 1 ;
const int FIRST_NAME_SIZE = 10 + 1;
const int LAST_NAME_SIZE = 12 + 1;
const int ID_SIZE         =   6 + 1;
const int TEST_SCORE_SIZE =   6    ;

int main(int argc, char * argv[])
{
   //PROTOTYPES
   int lowestScore(int *);
   double averageDropOne(int *, int);
   char letterGrade(double);
   void printHeader();
   void writeHeaderToFile(fstream &);
   void printResultToScreen(char *, char *, char *, int *, double, char);
   void writeResultToFile(char *, char *, char *, int *, double, char, fstream &);
   int getStudentInfo(const char *, char *, char *, char *, int *);

   //LOCAL DECLARATIONS
   fstream fin;
   fstream fout;
   char lineBuff[LINE_BUFF_SIZE];
   char fName[FIRST_NAME_SIZE];
   char lName[LAST_NAME_SIZE];
   char iD[ID_SIZE];
   int testScores[TEST_SCORE_SIZE];
   int lowest;
   double average;
   char grade;

   //PROCEDURES

   //Open data file and create output result file
   fin.open("student_input.dat", ios::in);
   if (!fin)
   {
      cout << "Cannot open data file. Program aborting. ";
      exit(1);
   }
   fout.open("student_results.dat", ios::out);
   if (!fout)
   {
      cout << "Cannot open output file. Program aborting. ";
      exit(1);
   }

   //display and write header
   printHeader();
   writeHeaderToFile(fout);

   //proceed
   while (fin.getline(lineBuff, LINE_BUFF_SIZE))
   {
      //parse student info line
      int studentInfo = getStudentInfo(lineBuff, fName, lName, iD, testScores);
      if (!studentInfo) //if getting an error while parsing
      {
         cout << "Error: Negative score input. Program aborting. ";
         exit(1);
      }
      else //parsing successfully
      {
         //calculate lowest score, average score and letter grade
         lowest = -1;
         if (studentInfo > 5)
            lowest = lowestScore(testScores);
         average = averageDropOne(testScores, lowest);
         grade = letterGrade(average);
         //output result to screen and file
         printResultToScreen(lName, fName, iD, testScores, average, grade);
         writeResultToFile(lName, fName, iD, testScores, average, grade, fout);
      }
   }

   fout.close();
   fin.close();
   cin.get();
   return 0;
}

//---------------------------------------------------------
// FUNCTION DEFINITIONS
//---------------------------------------------------------
//split and parse student info
//return number of test score (5 or 6) or 0 if getting an negative score or blank line
int getStudentInfo(const char *line, char *fName, char *lName, char *iD, int *scores)
{
   const char *PTR = line;
   char tempScore[10];
   int tmpScr = 0;
   char *sPtr = tempScore;
   int scoreCount = 0;

   if (!*PTR) //empty line, return 0
      return 0;
   //get first name
   while (*PTR != ' ' && *PTR != ' ')
      *fName++ = *PTR++;
   *fName = '';
   while (*PTR == ' ' || *PTR == ' ')
      PTR++;
   //get last name
   while (*PTR != ' ' && *PTR != ' ')
      *lName++ = *PTR++;
   *lName = '';
   while (*PTR == ' ' || *PTR == ' ')
      PTR++;
   //get id
   while (*PTR != ' ' && *PTR != ' ')
      *iD++ = *PTR++;
   *iD = '';
   while (*PTR == ' ' || *PTR == ' ')
      PTR++;
   //get all the test scores
   while (*PTR)
   {
      while (*PTR && *PTR != ' ' && *PTR != ' ')
         *sPtr++ = *PTR++;
      *sPtr = '';
      tmpScr = atoi(tempScore);
      if (tmpScr < 0) //negative score, return 0
         return 0;
      *scores++ = atoi(tempScore);
      sPtr = tempScore;
      scoreCount++;
      while (*PTR == ' ' || *PTR == ' ')
         PTR++;
   }
   //if scoreCount is not 6, then we must fill in the last test score
   //with an invalid score -1
   if (scoreCount != TEST_SCORE_SIZE)
      *scores = -1;
   return scoreCount;
}
//---------------------------------------------------------
int lowestScore(int *scores)
{
   int *lowest = scores;
   for (int *ptr = scores + 1; ptr - scores < TEST_SCORE_SIZE; ptr++)
   {
      if (*ptr < *lowest)
      {
         lowest = ptr;
      }
   }
   return *lowest;
}
//---------------------------------------------------------
double averageDropOne(int *scores, int scoreToDrop)
{
   double avg = 0.0;
   for (int *ptr = scores; ptr - scores < TEST_SCORE_SIZE; ptr++)
   {
      avg += *ptr;
   }
   return (avg - scoreToDrop) / (TEST_SCORE_SIZE - 1.0);
}
//---------------------------------------------------------
char letterGrade(double avg)
{
   if (avg >= 89.5)
      return 'A';
   if (avg >= 79.5)
      return 'B';
   if (avg >= 69.5)
      return 'C';
   if (avg >= 59.5)
      return 'D';
   return 'F';
}
//---------------------------------------------------------
void printHeader()
{
   cout << setw(LAST_NAME_SIZE) << left << "Last Name" << " "
        << setw(FIRST_NAME_SIZE) << left << "First Name" << " "
        << setw(ID_SIZE)         << right << "ID "       << "   "
        << setw(17) << "Test Scores"
        << setw(15) << "Average"
        << setw(8) << "Grade"
        << endl;
   int headerSize = LAST_NAME_SIZE + 1 + FIRST_NAME_SIZE + 1 + ID_SIZE + 3 + 17 + 15 +8;
   for (int i = 0; i < headerSize; i++)
      cout << "-";
   cout << endl;
}
//---------------------------------------------------------
void writeHeaderToFile(fstream &fout)
{
   fout << setw(LAST_NAME_SIZE) << left << "Last Name" << " "
        << setw(FIRST_NAME_SIZE) << left << "First Name" << " "
        << setw(ID_SIZE)         << right << "ID "       << "   "
        << setw(17) << "Test Scores"
        << setw(15) << "Average"
        << setw(8) << "Grade"
        << endl;
   int headerSize = LAST_NAME_SIZE + 1 + FIRST_NAME_SIZE + 1 + ID_SIZE + 3 + 17 + 15 +8;
   for (int i = 0; i < headerSize; i++)
      fout << "-";
   fout << endl;
}
//---------------------------------------------------------
void printResultToScreen(char *lName, char *fName, char *iD, int *scores, double avg, char grade)
{
   cout << setw(LAST_NAME_SIZE) << left << lName << " "
        << setw(FIRST_NAME_SIZE) << left << fName << " "
        << setw(ID_SIZE)         << right << iD    << "   ";
   for (int i = 0; i < TEST_SCORE_SIZE; i++)
   {
      cout << setw(3) << scores[i] << " ";
   }
   cout << fixed << setprecision(1)
        << setw(7) << avg
        << setw(7) << grade
        << endl;
}
//---------------------------------------------------------
void writeResultToFile(char *lName, char *fName, char *iD, int *scores, double avg, char grade, fstream &fout)
{
   fout << setw(LAST_NAME_SIZE) << left << lName << " "
        << setw(FIRST_NAME_SIZE) << left << fName << " "
        << setw(ID_SIZE)         << right << iD    << "   ";
   for (int i = 0; i < TEST_SCORE_SIZE; i++)
   {
      fout << setw(3) << scores[i] << " ";
   }
   fout << fixed << setprecision(1)
        << setw(7) << avg
        << setw(7) << grade
        << endl;
}