Computer Science 1622
Computer Science II

Programming Assignment 5
C++ (40 points)
Due Monday, February 22, 1998 (NO LATE PROGRAMS!!!)

The Problem

In this assignment you will implement a solution to the same problem you covered in program 4, but you will do it using C++. To make this task a little easier I will be including a set of code that will include all of the necessary data structures and functions, your job will be to simply finish the program.

In the C++ version of the program, each CD is a member of the class CD_Class and the whole table of CDs is represented by a single class instance of the class CD_Table_Class. The various routines that operate on the table are then implemented as functions that are part of the class CD_Table_Class. It is these functions that you will need to complete.

Note that access to the fields of the various classes is restricted to using accessor and mutator methods. Examples of how to access the various parts of the CD table are shown in the function Insert_CD which is associated with CD_Table_Class.

Here is a working copy of program 4. Use this as a guideline for finishing your program.

How to Proceed

I would recommend you start by getting the function Print_CD working first. Then you can run your code to see how things are working. Next I would get the Delete_CD routine working and test it. After that I would work on Sort_CDs_By_Rating. Once that is working (test it first), work on Sort_CDs_By_Name by copying your code from Sort_CDs_By_Rating and making the needed changes. Lastly, work on the routine Print_Categories. Make sure after you get each routine working to run the program and test that routine before moving on to the next routine.

Initial Code

#include <iostream.h>
#include <iomanip.h>
#include <string.h>

const int NAMELENGTH = 16;
const int MAXCDS = 25;
const int Alternative = 0;
const int ClassicRock = 1;
const int HeavyMetal = 2;
const int Pop = 3;
const int MAXCATEGORY = 4;

class Length_Class {
  // Class to represent time in minutes and seconds
  public:
    void set_minutes(int m) { minutes = m; }
    int get_minutes() { return minutes; }
    void set_seconds(int s) { seconds = s; }
    int get_seconds() { return seconds; }
  private:
    int minutes;
    int seconds;
};

class MC_Class {
  // Class to represent a group of music categories
  // Use the set_category and unset_category routines to mark
  //   a CD as being part of or not part of a category
  // Use get_category and one of the category constants 
  //   (e.g., Alternative) to determine if a
  //   CD is part of a category
  public:
    void set_category(int i) { in_category[i] = 1; }
    void unset_category(int i) { in_category[i] = 0; }
    int get_category(int i) { return in_category[i]; }
  private:
    int in_category[MAXCATEGORY];
};

class CD_Class {
  // Class to represent each CD
  public:
    void set_group_name(char *s) { strcpy(group_name,s); }
    char *get_group_name() { return group_name; }
    void set_CD_name(char *s) { strcpy(CD_name,s); }
    char *get_CD_name() { return CD_name; }
    void set_cost(float c) { cost = c; }
    float get_cost() { return cost; }
    void set_num_tracks(int n) { num_tracks = n; }
    int get_num_tracks() { return num_tracks; }
    void set_rating(float r) { rating = r; }
    float get_rating() { return rating; }
    Length_Class& get_length() { return length; }
    MC_Class& get_music_categories() { return music_categories; }
    void Print_CD(); // Used by Print_CDs
  private:
    char group_name[NAMELENGTH];
    char CD_name[NAMELENGTH];
    float cost;
    int num_tracks;
    float rating;
    Length_Class length;
    MC_Class music_categories;
};

class CD_Table_Class {
  // Class to represent an entire table of CDs
  public:
    void Insert_CD();
    void Delete_CD();
    void Print_Categories();
    void Sort_CDs_By_Name();
    void Sort_CDs_By_Rating();
    void Print_CDs();
    CD_Table_Class() {
      num_CDs = 0;
    }
  private:
    int num_CDs;
    CD_Class CDs[MAXCDS];
};

void Read_To_Newline(istream &thestream) {
  while (thestream.get() != '\n');
}

void Read_String_With_Spaces (char *string, int max_length) {
  cin.get(string,max_length,'\n');
  Read_To_Newline(cin);
}

void Menu() {
  cout << "Options: I)nsert D)elete printC)ats N)amesort R)atesort P)rintCDs Q)uit\n";
}

void CD_Table_Class::Insert_CD () {
  char c;
  int i;
  float f;
  char buffer[NAMELENGTH];

  if (num_CDs == MAXCDS)
    cout << "Unable to insert -- no more space!\n";
  else {
    cout << "Group name: ";
    Read_String_With_Spaces(buffer,NAMELENGTH);
    CDs[num_CDs].set_group_name(buffer);
    cout << "CD Title: ";
    Read_String_With_Spaces(buffer,NAMELENGTH);
    CDs[num_CDs].set_CD_name(buffer);
    cout << "Cost: ";
    cin >> f;
    CDs[num_CDs].set_cost(f);
    cout << "#Tracks: ";
    cin >> i;
    CDs[num_CDs].set_num_tracks(i);
    cout << "Rating: ";
    cin >> f;
    CDs[num_CDs].set_rating(f);
    cout << "Length - Minutes:Seconds: ";
    cin >> i >> c;
    CDs[num_CDs].get_length().set_minutes(i);
    cin >> i;
    CDs[num_CDs].get_length().set_seconds(i);
    for (i = 0; i < MAXCATEGORY; i++)
      CDs[num_CDs].get_music_categories().unset_category(i);
    do {
      cout << "Category to Add: A)lternative, C)lassicRock, H)eavyMetal, P)op, D)one: ";
      cin >> c;
      Read_To_Newline(cin);
      switch (c) {
        case 'A': case 'a':
          CDs[num_CDs].get_music_categories().set_category(Alternative);
          break;
        case 'C': case 'c':
          CDs[num_CDs].get_music_categories().set_category(ClassicRock);
          break;
        case 'H': case 'h':
          CDs[num_CDs].get_music_categories().set_category(HeavyMetal);
          break;
        case 'P': case 'p':
          CDs[num_CDs].get_music_categories().set_category(Pop);
          break;
        case 'D': case 'd':
          break;
        default:
          cout << "Unknown category starting with " << c << endl;
      }
    } while ((c != 'D') && (c != 'd'));
    cout << "Is this information correct (Y or y for yes)? ";
    cin >> c;
    Read_To_Newline(cin);
    if ((c == 'Y') || (c == 'y'))
      num_CDs++;
  }
}

void CD_Table_Class::Delete_CD () {

  // Your code here

}

void CD_Table_Class::Print_Categories () {

  // Your code here

}

void CD_Table_Class::Sort_CDs_By_Name () {

  // Your code here

}

void CD_Table_Class::Sort_CDs_By_Rating () {

  // Your code here

}

void CD_Class::Print_CD () {

  // Your code here

}

void CD_Table_Class::Print_CDs () {
  int i;

  cout << "Group           Title           Cost   Tr Lngth Rate Categories\n";
  cout << "-------------------------------------------------------------------------------\n";
  for (i = 0; i < num_CDs; i++)
    CDs[i].Print_CD();
}

void main() {
  CD_Table_Class cd_table;
  char option;

  cout.setf(ios::fixed,ios::floatfield);
  do {
    Menu();
    cout << "Option: ";
    cin >> option;
    Read_To_Newline(cin);
    switch (option) {
      case 'I': case 'i': cd_table.Insert_CD(); break;
      case 'D': case 'd': cd_table.Delete_CD(); break;
      case 'C': case 'c': cd_table.Print_Categories(); break;
      case 'N': case 'n': cd_table.Sort_CDs_By_Name(); break;
      case 'R': case 'r': cd_table.Sort_CDs_By_Rating(); break;
      case 'P': case 'p': cd_table.Print_CDs(); break;
      case 'Q': case 'q': break;
      default:
        cout << "Unknown menu option " << option << endl;
    }
    cout << endl;
  } while ((option != 'Q') && (option != 'q'));
}

What To Hand In

Hand in a full lab report for your program (consult the Programming Assignment Report Guidelines on what to include in this). Also include a listing of the data you used to test your program (you should discuss in your lab report what test data you used and whether this fully tests your solution). Finally you should attach output for your data showing that your program performs correctly.