#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXCDS 25
#define NAMELENGTH 16
typedef enum { MC_Alternative = 0, MC_ClassicRock, MC_HeavyMetal, MC_Pop } Music_Category;
#define MAXCATEGORY 4
typedef struct {
int minutes;
int seconds;
} Length_Struct;
typedef struct {
char group_name[NAMELENGTH];
char CD_name[NAMELENGTH];
float cost;
int num_tracks;
float rating;
Length_Struct length;
int in_category[MAXCATEGORY];
} CD_Struct;
void Read_To_Newline(FILE *stream) {
while (fgetc(stream) != '\n');
}
void Read_NameString_With_Spaces (char *string) {
scanf(" %15[^\n]",string);
Read_To_Newline(stdin);
}
void Menu() {
printf("Options: I)nsert D)elete printC)ats N)amesort R)atesort P)rintCDs Q)uit\n");
}
void Insert_CD (CD_Struct CDs[], int *num_CDs) {
int cat;
char option;
float f;
int i1;
int i2;
char tempname[NAMELENGTH];
if (*num_CDs == MAXCDS)
printf("Unable to insert -- no more space!\n");
else {
printf("Group name: ");
Read_NameString_With_Spaces(tempname);
strcpy(CDs[*num_CDs].group_name,tempname);
printf("CD Title: ");
Read_NameString_With_Spaces(tempname);
strcpy(CDs[*num_CDs].CD_name,tempname);
printf("Cost: ");
scanf("%f",&f);
CDs[*num_CDs].cost = f;
printf("#Tracks: ");
scanf("%d",&i1);
CDs[*num_CDs].num_tracks = i1;
printf("Rating: ");
scanf("%f",&f);
CDs[*num_CDs].rating = f;
printf("Length - Minutes:Seconds: ");
scanf("%d %*c%d",&i1,&i2);
CDs[*num_CDs].length.minutes = i1;
CDs[*num_CDs].length.seconds = i2;
for (cat = 0; cat < MAXCATEGORY; cat++)
CDs[*num_CDs].in_category[cat] = 0;
do {
printf("Category to Add: A)lternative, C)lassicRock, H)eavyMetal, P)op, D)one: ");
scanf(" %c",&option);
Read_To_Newline(stdin);
switch (option) {
case 'A': case 'a':
CDs[*num_CDs].in_category[MC_Alternative] = 1;
break;
case 'C': case 'c':
CDs[*num_CDs].in_category[MC_ClassicRock] = 1;
break;
case 'H': case 'h':
CDs[*num_CDs].in_category[MC_HeavyMetal] = 1;
break;
case 'P': case 'p':
CDs[*num_CDs].in_category[MC_Pop] = 1;
break;
case 'D': case 'd':
break;
default:
printf("Unknown category starting with %c\n",option);
}
} while ((option != 'D') && (option != 'd'));
printf("Is this information correct (Y or y for yes)? ");
scanf(" %c",&option);
Read_To_Newline(stdin);
if ((option == 'Y') || (option == 'y'))
*num_CDs = *num_CDs + 1;
}
}
void Delete_CD (CD_Struct CDs[], int *num_CDs) {
char dgroup[NAMELENGTH];
char dtitle[NAMELENGTH];
int D;
char option;
printf("Group Name: ");
Read_NameString_With_Spaces(dgroup);
printf("CD Title: ");
Read_NameString_With_Spaces(dtitle);
for (D = 0; (D < *num_CDs) && (strcmp(dgroup,CDs[D].group_name) || strcmp(dtitle,CDs[D].CD_name)); D++);
if (D >= *num_CDs)
printf("Unable to delete, CD not found!\n");
else {
printf("Are you sure you want to delete this CD? ");
scanf(" %c",&option);
if ((option == 'Y') || (option == 'y')) {
if (D < (*num_CDs - 1))
CDs[D] = CDs[*num_CDs - 1];
*num_CDs = *num_CDs - 1;
}
}
}
void Print_Categories (CD_Struct CDs[], int num_CDs) {
Music_Category cat;
int I;
int count;
float rate;
float cost;
printf("Type # AvgCost AvgRate\n");
printf("------------------------------\n");
for (cat = MC_Alternative; cat <= MC_Pop; cat++) {
switch (cat) {
case MC_Alternative: printf("Alternative"); break;
case MC_ClassicRock: printf("ClassicRock"); break;
case MC_HeavyMetal : printf("HeavyMetal "); break;
case MC_Pop : printf("Pop "); break;
}
count = 0;
rate = 0.0;
cost = 0.0;
for (I = 0; I < num_CDs; I++)
if (CDs[I].in_category[cat]) {
count++;
rate += CDs[I].rating;
cost += CDs[I].cost;
}
if (count == 0)
printf(" 0 - -\n");
else
printf("%2d%7.2f%7.2f\n",count,(cost / count),(rate / count));
}
}
void Sort_CDs_By_Name (CD_Struct CDs[], int num_CDs) {
int minCD, I, J, compareval;
CD_Struct temp;
for (I = 0; I < (num_CDs - 1); I++) {
minCD = I;
for (J = I+1; J < num_CDs; J++) {
compareval = strcmp(CDs[J].group_name,CDs[minCD].group_name);
if ((compareval < 0) || ((compareval == 0) && (strcmp(CDs[J].CD_name,CDs[minCD].CD_name) < 0)))
minCD = J;
}
temp = CDs[I];
CDs[I] = CDs[minCD];
CDs[minCD] = temp;
}
}
void Sort_CDs_By_Rating (CD_Struct CDs[], int num_CDs) {
int minCD, I, J;
CD_Struct temp;
for (I = 0; I < (num_CDs - 1); I++) {
minCD = I;
for (J = I+1; J < num_CDs; J++)
if (CDs[J].rating > CDs[minCD].rating)
minCD = J;
temp = CDs[I];
CDs[I] = CDs[minCD];
CDs[minCD] = temp;
}
}
void Print_CD (CD_Struct CD) {
Music_Category cat;
int print_comma = 0;
printf("%-16s%-16s%5.2f%4d%3d:%02d%5.1f ",CD.group_name,CD.CD_name,CD.cost,CD.num_tracks,CD.length.minutes,CD.length.seconds,CD.rating);
for (cat = MC_Alternative; cat <= MC_Pop; cat++)
if (CD.in_category[cat]) {
if (print_comma) printf(", ");
switch (cat) {
case MC_Alternative: printf("Alternative"); break;
case MC_ClassicRock: printf("ClassicRock"); break;
case MC_HeavyMetal: printf("HeavyMetal"); break;
case MC_Pop: printf("Pop"); break;
}
print_comma = 1;
}
printf("\n");
}
void Print_CDs (CD_Struct CDs[], int num_CDs) {
int I;
printf("Group Title Cost Tr Lngth Rate Categories\n");
printf("-------------------------------------------------------------------------------\n");
for (I = 0; I < num_CDs; I++)
Print_CD(CDs[I]);
}
void main() {
int num_CDs = 0;
CD_Struct CDs[MAXCDS];
char option;
do {
Menu();
printf("Option: ");
scanf(" %c",&option);
Read_To_Newline(stdin);
switch (option) {
case 'I': case 'i': Insert_CD(CDs,&num_CDs); break;
case 'D': case 'd': Delete_CD(CDs,&num_CDs); break;
case 'C': case 'c': Print_Categories(CDs,num_CDs); break;
case 'N': case 'n': Sort_CDs_By_Name(CDs,num_CDs); break;
case 'R': case 'r': Sort_CDs_By_Rating(CDs,num_CDs); break;
case 'P': case 'p': Print_CDs(CDs,num_CDs); break;
case 'Q': case 'q': break;
default:
printf("Unknown menu option %c!\n",option);
}
printf("\n");
} while ((option != 'Q') && (option != 'q'));
}