CSC 161 Program #2

"Gradebook"
75 points
Assigned: Mon Jun 30, 2003 Due: Fri Jul 11, 2003

Concepts

The "new" concepts covered in this program are:

  • the use of pointers in C++ including pointer arithmetic and the -> operator

  • dynamic memory allocation using new and delete

We will also review a couple of the basics from good old CSC 160: basic file I/O and sorting.

Description

The Gradebook program manages the assignment scores for a class of students. The program should have the following basic capabilities:
  1. Read in a file of student scores
  2. Change grades in an interactive session
  3. View grades, sorted by score, in an interactive session
  4. Write a new file of student scores, if requested by the user

READ - A Gradebook session starts with reading a scores file specified by the user. The format of this file is given below.

CHANGE - When the user elects to change grades, the user is shown all the possible categories and must choose one. Then, the user is shown each student in the class and enters a score for the student on the selected assignment.

VIEW - When viewing student scores, the user again must first choose the category to be viewed. Then, student scores on that assignment must be listed in descending order based on their score for that assignment.

WRITE - Upon exiting, the user must be given the opportunity to save scores to a new file. You should only ask the user this if he/she has made changes to the scores.

Student Scores File Format

The format of the student scores file is:

<num_scores>,<num_students>
<category1>,<category2>, ... <categoryN>
<student1>,<score1>,<score2>, ... <scoreN>
<student2>,<score1>,<score2>, ... <scoreN>
...
<studentN>,<score1>,<score2>, ... <scoreN>

The first line of the file defines the number of scores, <num_scores>, and number of students, <num_students>, for this class. 

The second line holds <num_scores> strings separated by commas. These strings define the names of the assignments for each score, things like "Homework" or "Final Exam".

The remainder of the file contains <num_students> lines of scores, one per student. Each line should contain the student's name and then <num_scores> integers defining the scores for that student.

Example Session

Here's a possible example session (user input in bold/underline and shortcuts are C++ commented with //):

** GradeBook! **
 
Enter scores file name> scores.txt
5 students score records read in
 
1. Change grades
2. Show grades
3. Exit
Enter choice (1-3)> 1
Score categories:
    Homework           Lab
    Program #1         Program #2
    Program #3         Program #4
    Program #5         Midterm exam
    Final exam
Enter category> Program #2
Change scores for Program #2
    Enter grade for Bill Krieger> 80
    Enter grade for Dusty Baker> 72
    // continue for all students
 
// show menu again
Enter choice (1-3)> 2
// show score categories again
Enter category> Homework
    Student           Score
    Dusty Baker          20
    Bill Krieger         19
    // continue showing sorted student scores
 

Implementation

Your implementation must use pointers, rather than array subscripting throughout your program. Your objects and arrays should also be dynamically allocated wherever possible.

Your implementation must use classes in an object-oriented approach. As a hint, I used the following classes in my solution:

  • Gradebook - my Gradebook holds two important arrays. First, it contains an array of of score category names (like "Midterm", "Program #1", etc). Second, it contains an array of StudentScores objects. Of course, with each array, the number of items in each must be stored in a variable. Finally, my Gradebook has a bool variable that is set true when any scores in the Gradebook are changed. Among other member functions,I have a Gradebook constructor that accepts the number of scores and number of students for this Gradebook. This constructor dynamically allocates the array I mentioned above.
  • StudentScores - these objects store the name of a student and then an array of his/her scores.

Other hints:

  • Page 937 describes a version of function getline that accepts a delimiter argument. Also, don't forget to "gobble" newline characters! We'll talk about this in class.
  • You must sort your student scores without changing the original array of data as it was read in. To do this (using the parlance of my solution), you need an array StudentScores pointers. There is a solution similar to this on pages 675-683 in our text.
  • Please create a destructor for any class that dynamically allocates memory. Delete any memory created for the object in the destructor.
  • Remember that all arrays must be dynamically allocated. So, for example an array of integers must be declared as a pointer:

    int *scores ;

    Also remember that arrays must be accessed using pointer arithmetic, rather than subscripting. For example:

    scores[i] = 10 ;

    must be replaced by:

    *(scores + i) = 10 ;

  • Most of you will also have an array of StudentScores (or similar) objects. You can use the (what did the book call it again... hold on a second...ah, got it), the structure pointer operator, or ->, like this:

    StudentScores *students ;

    // Call of a member function of the i'th student

    cout << (students + i)->getName() ;

  • When dynamically allocating an array of objects, only the default constructor can be used, like this:

    students = new StudentScores[ numStudents] ;

    There is no way to call a constructor with arguments when creating an array of objects. You'll have to call separate member functions to further specify StudentScores or other objects after they are created.

  • Make your classes as generic and reusable as possible. Do not put all user interaction in your GradeBook class, put it into main.
  • Try reading in a GradeBook file that you have written.

Grading

Your program will be graded on three areas: design, quality, and function. Their description and weighting in your grade is given below.

1. Program Design (20%, 15 points)

For most of our programs, your program design will be encapsulated in your class header files. Your classes should be consistent and created with an eye toward reuse by other programs.

2. Program quality (20%, 15 points)

Your program should be clean and well-commented. More coming on this later.

3. Program function (60%, 45 points)

If your program doesn't compile or link, your grade for this section will automatically be cut in half and then I'll start from there. Please leave a README file in your folder with notes you want me to read.

Notes

I have placed two test files in the Common Area: prog02/scores.txt and prog02/scores2.txt

July 7, 2003... Forget about my scores2.txt; it's the same as scores.txt. So, you're only responsible for running your program on scores.txt and at least one example of your own creation.

July 8, 2003... In the hints above, I mentioned "gobbling" newline characters. Please note that if you use the stream operator ">>" to read integer data from a file, you may also need to consume the commas between the integers. For example, to read a line containing two comma-separated integers from a file, you'd need something like this:

ifstream f ;
int x, y ;
 
f >> x ;
f.ignore() ;
f >> y ;
f.ignore() ;