//prelim.cpp

#include <iostream>
#include <fstream>


// -------------------------------------
// Global constants and type definitions
// -------------------------------------

const int NUMBER_OF_QUIZZES = 5;
typedef float QuizArray[NUMBER_OF_QUIZZES];
const int MAX_NAME_LENGTH = 40;  // last name first;
                                 // includes spaces between
                                 // parts of name.
typedef char NameText[MAX_NAME_LENGTH + 1];

struct Student  {
   int iD;
   NameText name;
   QuizArray quizzes;
};

const int MAX_NUMBER_OF_STUDENTS = 40;
typedef Student Roster[MAX_NUMBER_OF_STUDENTS];


// -----------------------------------
// Prototypes for file input functions
// -----------------------------------

bool readStudents(const char inputFilename[],
                  Roster roster,
                  int& numberOfStudents);
void skipRestOfLine(istream& in, char& x);


// --------------------------------------
// Prototypes for functions you must call
// --------------------------------------

void printStudentName(const Student& student);
void printText(char text[]);
void printLetter(char x);
void printScore(float x);


// -------------
// Main function
// -------------

int main()
{
   // Read student data from data file:
   const char filename[] = "quizRoster.txt";
   Roster students;
   int numberOfStudents;
   if ( ! readStudents(filename,    // uses cout
                       students,
                       numberOfStudents) )
      return 1;


   // ---------------------------------
   // Insert other function calls here.
   // ---------------------------------

   printStudentName(students[2]);
   printText(students[3].name);
   printLetter(students[1].name[0]);
   printScore(students[0].quizzes[0]);

   return 0;
}  // main

// -----------------------
// Functions you must call
// -----------------------

void printStudentName(const Student& student)
{
   cout << "Calling printStudentName(const Student& student):  "
                  << "student.name = "
                  << student.name << endl;
}  // printStudentName

void printText(char text[])
{
   cout << "Calling printText(char[] text):  text = "
                  << text << endl;
}  // printScore

void printLetter(char x)
{
   cout << "Calling printLetter(char x):  x = " << x << endl;
}  // printScore

void printScore(float x)
{
   cout << "Calling printscore(float x):  x = " << x << endl;
}  // printScore




// -----------------------
// Function for file input
// -----------------------

/*
 * bool readStudents(const char inputFilename[],
 *                   Roster roster,
 *                   int& numberOfStudents)
 *
 * Reads all the student information in
 * the specified text file and loads it,
 * as one record per student, into roster.
 *
 * An error message is printed if the
 * file is not found, is not readable,
 * or contains a number format error
 * beyond the first item on a line.
 *
 * Parameters:
 *    inputFilename - filename of text file
 *          to read from.  The format of the
 *          text file must be:  one student
 *          per line, with columns for (1) ID,
 *          (2) 5 quiz scores, and (3) names,
 *          last names first.  All data items
 *          on a line are separated by
 *          whitespace (spaces or tabs).
 *    roster - an array of Student records.
 *       Precondition:  none.
 *       Postcondition:  roster contains all
 *          the student information in the
 *          input file, if input has not failed.
 *    numberOfStudents - count of records in roster.
 *       Precondition:  none.
 *       Postcondition:  number of students
 *          is the number of records that
 *          have been read into roster.
 *
 * Global variable:
 *    cout - output stream to terminal window.
 *         An object of class ostream,
 *         declared in header file <iostream>.
 *      Precondition:  The state of cout is true,
 *         and cout is ready to begin a line.
 *      Postcondition:  The state of cout is still
 *         true, and cout has ended a line.
 *
 * Returns:
 *    true if input was successful, false otherwise.
 */
bool readStudents(const char inputFilename[],
                  Roster roster,
                  int& numberOfStudents)
{
   // Prepare to read from input file:
   ifstream inFile;
   inFile.open(inputFilename);
   if ( !inFile )  {
      cout << "Could not read "
                  << inputFilename << "." << endl;
      return false;
   }  // if

   // Read data for each student into a location
   // in roster array corresponding to the number
   // of student records previously read:
   numberOfStudents = 0;    // records previously read
   while ( numberOfStudents < MAX_NUMBER_OF_STUDENTS )  {

      // Attempt to read ID, first item on line:
      inFile >> roster[numberOfStudents].iD;

      // Quit reading if at end of file:
      if ( !inFile )
         break;

      // Read quiz scores:
      for ( int i = 0; i < NUMBER_OF_QUIZZES; i++ )
         inFile >> roster[numberOfStudents].quizzes[i];

      // Check for format error:
      if ( !inFile )  {
          cout << inputFilename
                   << " format error at line "
                   << (numberOfStudents + 1) << endl;
          return 1;
      }  // if

      // skip white space:
      char x;
      do  {
         inFile.get(x);
      } while ( x == ' ' || x == '\t' );

      // Read name:
      int nameIndex = 0;
      while ( x != '\n' && nameIndex < MAX_NAME_LENGTH )
      {
         roster[numberOfStudents].name[nameIndex] = x;
         inFile.get(x);
         nameIndex++;
      }  // while

      // Skip any remaining characters on the line:
      skipRestOfLine(inFile, x);
      while ( x != '\n')
         inFile.get(x);

      // Terminate C-string:
      roster[numberOfStudents].name[nameIndex] = '\0';

      // next Student in array:
      numberOfStudents++;
   }  // while

   // Release handle on file, so it can be re-used:
   inFile.close();

   return true;
}  // function readStudents



/*
 * void skipRestOfLine(istream& in, char& x)
 *
 * Reads any remaining characters on the
 * current line of input.
 *
 * The end-of-line marker is assumed to
 * consist of or end with a newline
 * character ('\n').
 *
 *    in - an input stream.
 *       Precondition:  The state of in is true.
 *       Postcondition:  The state of in is still
 *          true, and in has ended a line.  If
 *          x was originally '\n' (which should
 *          be the case only if in was originally
 *          ready to begin a reading a line), then
 *          no more characters have been read.
 *    x - the character most recently read,
 *          either by this function (if it reads
 *          any characters) or previously.
 *       Precondition:  x is the character most
 *          recently read before this function
 *          was called.
 *       Postcondition:  x equals '\n'.
 */
void skipRestOfLine(istream& in, char& x)
{
   while ( x != '\n' )   // Unix end-of-line
      in.get(x);
}  // function skipRestOfLine(istream&, char&)