header
/*---------------------------------------------------------
| SAT Report
|
|
| This program reads generates a report about SAT scores
| based on data read from a text file. Each line of data
| represents one record formatted as follows:
|
| Width        Field
| -----        -------------------------------------
|   6          Student ID (Always 6 characters)
|   9          Last Name  (Maximum of 9 characters)
|   7          First Name (Maximum of 7 characters)
|   3          SAT Verbal (Maximum of 3 digits)
|   3          SAT Math   (Maximum of 3 digits)
|
| This program assumes that there are no errors in the
| data file.
|
| For each student, the report displays the student's name
| (in lastName, firstName format), the student's ID, the
| SAT math score, the verbal score, and the combined score.
|
| D. Searls
| Asbury College
| Feb 2002
---------------------------------------------------------*/
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
const int MAXSIZE = 100;

class student
{
private:
    string identifier;
    string firstName;
    string lastName;
    int verbalSAT;
    int mathSAT;
    
public:
    // Constructors
    //-----------------------------------------------------
    // Construct a default student. The identifier, first
    // name, and last name will be empty strings and the
    // verbal and math SAT scores will be set to zero.
    //-----------------------------------------------------
    student()
    {
        identifier = "";
        firstName = "";
        lastName = "";
        verbalSAT = 0;
        mathSAT = 0;
    }
    //-----------------------------------------------------
    // Construct a new student with the specified parameters.
    //
    // Precondition: math and verbal SAT scores must be
    // between 0 and 800 (inclusive). Otherwise, the
    // corresponding score will be set to zero.
    //
    // In parameters: id, first, last, verbal, math
    //-----------------------------------------------------
    student(string id, string first, string last,
            int verbal, int math)
    {
        identifier = id;
        firstName = first;
        lastName = last;
        if (verbal >= 0 && verbal <= 800)
        {
            verbalSAT = verbal;
        }
        else
        {
            verbalSAT = 0;
        }
        if (math >= 0 && math <= 800)
        {
            mathSAT = math;
        }
        else
        {
            mathSAT = 0;
        }
    }
    //-----------------------------------------------------
    // Construct a new student with the same state as the
    // specified student.
    //
    // In parameter: stu
    //-----------------------------------------------------
    student(const student& stu)
    {
        identifier = stu.identifier;
        firstName = stu.firstName;
        lastName = stu.lastName;
        verbalSAT = stu.verbalSAT;
        mathSAT = stu.mathSAT;
    }
    // Member functions
    //-----------------------------------------------------
    // Reset the state of the student to the specified
    // values.
    //
    // Precondition: math and verbal SAT scores must be
    // between 0 and 800 (inclusive). Otherwise, the
    // corresponding score will be left unchanged.
    //
    // In parameters: newId, newFirst, newLast, newVerbal,
    //                newMath
    //-----------------------------------------------------
    void reset(string newId, string newFirst, string newLast,
               int newVerbal, int newMath)
    {
        identifier = newId;
        firstName = newFirst;
        lastName = newLast;
        if (newVerbal >= 0 && newVerbal <= 800)
        {
            verbalSAT = newVerbal;
        }
        if (newMath >= 0 && newMath <= 800)
        {
            mathSAT = newMath;
        }
    }
    //-----------------------------------------------------
    // Return this student's identifier.
    //-----------------------------------------------------
    string getIdentifier() const
    {
        return identifier;
    }
    //-----------------------------------------------------
    // Return this student's first name.
    //-----------------------------------------------------
    string getFirstName() const
    {
        return firstName;
    }
    //-----------------------------------------------------
    // Return this student's last name.
    //-----------------------------------------------------
    string getLastName() const
    {
        return lastName;
    }
    //-----------------------------------------------------
    // Return this student's verbal SAT score.
    //-----------------------------------------------------
    int getVerbalSAT() const
    {
        return verbalSAT;
    }
    //-----------------------------------------------------
    // Return this student's math SAT score.
    //-----------------------------------------------------
    int getMathSAT() const
    {
        return mathSAT;
    }
    //-----------------------------------------------------
    // Return this student's combined SAT score.
    //-----------------------------------------------------
    int getCombinedSAT() const
    {
        return mathSAT + verbalSAT;
    }
};
//---------------------------------------------------------
// trim
//
// Returns: the string parameter with any leading and/or
//   trailing whitespace characters removed. Characters with
//   ASCII codes of 32 (blank) or less are considered white
//   space.
//
// In: str
//---------------------------------------------------------
string trim(string str)
{
    int posFirst;  // position of first non-whitespace character
    int posLast;   // position of last non-whitespace character
    int length;
    // Find position of first non-whitespace character
    length = str.length();  // The length of the string
    posFirst = 0;
    while(posFirst < length && str.at(posFirst) <= ' ')
        posFirst++;
    // Find position of last non-whitespace character
    posLast = length - 1;
    while(posLast > posFirst && str.at(posLast) <= ' ')
        posLast--;
    return str.substr(posFirst, posLast - posFirst + 1);
}
//---------------------------------------------------------
// readStudentRecords
//
// Read the student records from the input file.
//
// Out parameters: stu, n
//---------------------------------------------------------
void readStudentRecords(student stu[], int& n)
{
    ifstream infile;
    string filename;
    string oneLine;
    cout << "Enter name of input file (try 'SAT.dat'): ";
    cin >> filename;
    infile.open(filename.c_str());
    if (!infile.fail())
    {
        n = 0;
        getline(infile, oneLine);
        while (!infile.fail() && n < MAXSIZE)
        {
            stu[n].reset(oneLine.substr(0,6),
                         trim(oneLine.substr(15,7)),
                         trim(oneLine.substr(6,9)),
                         atoi(oneLine.substr(22,3).c_str()),
                         atoi(oneLine.substr(25,3).c_str()));
            n = n + 1;
            getline(infile, oneLine);
        }
    }
    else
    {
        cout << "Could not open input file " << filename << "!\n\n";
        cout << "Program abnormally terminated.\n\n";
        exit(0);
    }
}
//---------------------------------------------------------
// displayStudentRecords
//
// Display the student records.
//
// In parameters: stu, n
//---------------------------------------------------------
void displayStudentRecords(const student stu[], int n)
{
    cout << endl;
    cout << "                 SAT Scores Report" << endl;
    cout << endl;
    cout << "----------------------------------------------------" << endl;
    cout << "Student Name          ID      Math  Verbal  Combined" << endl;
    cout << "----------------------------------------------------" << endl;
    for (int i = 0; i < n; i++)
    {
        cout << left;
        cout << setw(18) << stu[i].getLastName() + ", " + stu[i].getFirstName();
        cout << right;
        cout << setw(8) << stu[i].getIdentifier();
        cout << setw(8) << stu[i].getMathSAT();
        cout << setw(8) << stu[i].getVerbalSAT();
        cout << setw(10) << stu[i].getCombinedSAT();
        cout << endl;
    }
    cout << "----------------------------------------------------" << endl;
    cout << endl << endl;
}

//*********************************************************
//        M  A  I  N
//*********************************************************
int main()
{
    student stu[MAXSIZE];
    int n;
    readStudentRecords(stu, n);
    displayStudentRecords(stu, n);
    return 0;
}