#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')); }