Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Many of us have large digital music collections that are not always very well or

ID: 663517 • Letter: M

Question

Many of us have large digital music collections that are not always very well organized. It would be nice to have a program that would arrange our music collection based attributes such as artist, album title, song title, genre, song length, number times played, and rating. For this assignment you will write a digital music manager (DMM).

Your DMM program must have a text-based interface which allows the user to select from a menu of options including: load, store, display, insert, delete, edit, sort, rate, and exit. The load option reads records from a file into a dynamic doubly linked list. The store command writes records, in a dynamic doubly linked list, to a file. Display prints records, and its attributes to the screen. This command must print either all records or a single record based on a search field. A search field may be any of the attributes belonging to a record. If a search field matches multiple records, then print the first match to the screen. The insert option collects information for each new song record and attributes from the user. The new song record must be placed into the list based on a selected sort option. By default, songs are inserted into the list alphabetically (a z) according to artist. Other possible sort options include alphabetical ordering based on genre, or increasing numeric value based on rating. Delete removes a record from the list. Deletion is based on song title. The edit option must allow the user to find a record in the list with any search field. The user may modify any of the attributes in the record. The rate action must allow the user to assign a value of 1 5 to a song; 1 is the lowest rating and 5 is the highest rating. Lastly, exit saves the most recent list to a file.

PLEASE WRITE IN C.

A record is a struct type which consists of the following attributes:

IV. Logical Block Diagram

The logical block diagram for your doubly linked list should look like the following:

As you can see from the illustration a doubly linked list has a pointer to the next node and the previous node in the list. The first nodes previous node pointer is always NULL and the last nodes next pointer is always NULL. When you insert and delete nodes from a doubly linked list, you must always carefully link the previous and next pointers.

PLEASE WRITE IN C.

Explanation / Answer

#include "DMM.h" /************************************************************************* * Description: Reads strings from a file *************************************************************************/ char* readStr(FILE *infile) { char *pStr = NULL; char str[100]; fgets(str, 100, infile); str[strlen(str)-1] = ''; pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); return pStr; } /************************************************************************* Description: Inputs music node from file ************************************************************************/ Node* readItem(FILE *infile) { Node *pNewItem = NULL; char tempChar; pNewItem = (Node*)malloc(sizeof(Node)); pNewItem->pArtist = readStr(infile); pNewItem->pSongTitle = readStr(infile); pNewItem->pAlbumTitle = readStr(infile); pNewItem->pGenre = readStr(infile); fscanf(infile, "%lf", &(pNewItem->songLength)); fscanf(infile, "%d", &(pNewItem->numTimesPlayed)); fscanf(infile, "%d", &(pNewItem->rating)); fscanf(infile, "%c", &tempChar); pNewItem->pPrevious = NULL; pNewItem->pNext = NULL; return pNewItem; } /************************************************************************* * Description: Prints individual node to console *************************************************************************/ void printNode(Node *pItem) { printf(" Artist: "); puts(pItem->pArtist); printf("Song Title: "); puts(pItem->pSongTitle); printf("Album Title: "); puts(pItem->pAlbumTitle); printf("Genre: "); puts(pItem->pGenre); printf("Song Length: %.2lf ", pItem->songLength); printf("Number of Plays: %d ", pItem->numTimesPlayed); printf("Rating: %d ", pItem->rating); } /************************************************************************* * Description: Initializes list, sets start and end to null; ******************************************************************/ List* initList(void) { List *pList = (List*)malloc(sizeof(List)); pList->pStart = NULL; pList->pEnd = NULL; return pList; } /************************************************************************* * Description: Checks if list is empty ***********************************************************************/ Boolean isEmpty(List *pList) { Boolean empty = FALSE; if(NULL == pList->pStart) { empty = TRUE; } return empty; } /************************************************************************* * Description: Prints entire list to console **********************************************************************/ void printList(List *pList) { Node* conductor = pList->pStart; while(NULL != conductor) { printNode(conductor); conductor = conductor->pNext; } } /************************************************************************* * Description: Adds node to list in user determined order *************************************************************************/ void addItemToList(List **pList, Node **item, int sortType) { Boolean found = FALSE; char pStr[100]; double tempDouble = 0; int tempInt = 0; Node* conductor = (*pList)->pStart; if(TRUE == isEmpty(*pList)) { (*pList)->pStart = *item; (*pList)->pEnd = *item; } else { //Find where to insert item switch(sortType) { case 1: strcpy(pStr, (*item)->pSongTitle); break; case 2: strcpy(pStr, (*item)->pAlbumTitle); break; case 3: strcpy(pStr, (*item)->pGenre); break; case 4: tempDouble = (*item)->songLength; break; case 5: tempInt = (*item)->numTimesPlayed; break; case 6: tempInt = (*item)->rating; break; case 0: //Fall through default: strcpy(pStr, (*item)->pArtist); break; } while(NULL != conductor && !found) //While not at the end of the list && placement not found continue down the list { switch(sortType) { case 1: if(strcmp(pStr, conductor->pSongTitle) < 0) { found = TRUE; } break; case 2: if(strcmp(pStr, conductor->pAlbumTitle) < 0) { found = TRUE; } break; case 3: if(strcmp(pStr, conductor->pGenre) < 0) { found = TRUE; } break; case 4: if(tempDouble > conductor->songLength) { found = TRUE; } break; case 5: if(tempInt > conductor->numTimesPlayed) { found = TRUE; } break; case 6: if(tempInt > conductor->rating) { found = TRUE; } break; case 0: //Fall through default: if(strcmp(pStr, conductor->pArtist) < 0) { found = TRUE; } break; } if(!found) //If placement not found continue down the list { conductor = conductor->pNext; } } if(NULL == conductor) //if item is to be inserted at end of list { (*item)->pPrevious = (*pList)->pEnd; (*pList)->pEnd->pNext = (*item); (*pList)->pEnd = (*item); } else if(NULL == conductor->pPrevious) //If item is to be inserted at front of list { (*item)->pNext = (*pList)->pStart; (*pList)->pStart->pPrevious = (*item); (*pList)->pStart = (*item); } else //If item to be inserted between two other nodes { conductor->pPrevious->pNext = (*item); (*item)->pNext = conductor; (*item)->pPrevious = conductor->pPrevious; conductor->pPrevious = (*item); } } } /************************************************************************* Description: Writes list to file *****************************************************************/ void saveList(List *pList, FILE *outfile) { Node *conductor = pList->pStart; while(NULL != conductor) { fputs(conductor->pArtist, outfile); fprintf(outfile, " "); fputs(conductor->pAlbumTitle, outfile); fprintf(outfile, " "); fputs(conductor->pSongTitle, outfile); fprintf(outfile, " "); fputs(conductor->pGenre, outfile); fprintf(outfile, " "); fprintf(outfile, "%.2f ", conductor->songLength); fprintf(outfile, "%d ", conductor->numTimesPlayed); fprintf(outfile, "%d ", conductor->rating); conductor = conductor->pNext; } } /************************************************************************* * Description: Resorts list in user determined way *************************************************************************/ List* resortList(List *pList, int sortType) { List *pNewList = NULL; Node* conductor = pList->pStart; Node* tempNode = NULL; pNewList = initList(); while(NULL != conductor) { pList->pStart = pList->pStart->pNext; conductor->pNext = NULL; conductor->pPrevious = NULL; addItemToList(&pNewList, &conductor, sortType); conductor = pList->pStart; } free(pList); return pNewList; } /************************************************************************* * Description: Displays main menu ************************************************************************/ void displayMenu(void) { printf("***** Digital Music Manager menu ***** "); printf("1. Load music from file "); printf("2. Save music list to file "); printf("3. Print music list to screen "); printf("4. Print individual record to screen "); printf("5. Change list sorting option "); printf("6. Insert new record "); printf("7. Edit record "); printf("8. Delete record "); printf("9. Rate song "); printf("10. Exit Music Manager "); } /************************************************************************* * Description: Gets and validates users main menu choice *************************************************************************/ int getMenuChoice(void) { int choice = 0; do { _flushall; printf("Enter your menu choice: "); scanf("%d", &choice); if(choice < 1 || choice > 10) { printf("Invalid choice, choose an option between 1 and 6 "); } }while(choice < 1 || choice > 10); return choice; } /************************************************************************* * Description: Displays sorting options ********************************************************************/ void displaySortingOptions(void) { printf(" *** Sorting Options *** "); printf("1. Artist "); printf("2. Song Title "); printf("3. Album Title "); printf("4. Genre "); printf("5. Song Length "); printf("6. Number of Plays "); printf("7. Rating "); } /************************************************************************* Description: Gets and validates users sort menu option ************************************************************************/ int getSortingOption(void) { int choice = 0; do { printf(" Enter your choice: "); scanf("%d", & choice); if(choice < 1 || choice > 7) { printf("Invalid choice, enter a number between 1 and 7 "); } }while(choice < 1 || choice > 7); return (choice - 1); } /************************************************************************* Description: displays search options to console *************************************************************************/ void displaySearchOption(void) { printf(" *** Searching Option *** "); printf("1. Artist "); printf("2. Song Title "); printf("3. Album Title "); printf("4. Genre "); printf("5. Number of Plays "); printf("6. Rating "); } /************************************************************************* * Description: Searches through list for user determined node *************************************************************************/ Node *searchListString(List *pList, int searchOption, char *str) { Boolean found = FALSE; Node *conductor = pList->pStart; Node *pMem = NULL; while(found == FALSE && conductor != NULL) { switch(searchOption) { case 1: if(strcmp(str, conductor->pArtist) == 0) { pMem = conductor; } break; case 2: if(strcmp(str, conductor->pSongTitle) == 0) { pMem = conductor; } break; case 3: if(strcmp(str, conductor->pAlbumTitle) == 0) { pMem = conductor; } break; case 4: if(strcmp(str, conductor->pGenre) == 0) { pMem = conductor; } break; } if(!found) { conductor = conductor->pNext; } } return pMem; } /************************************************************************* * Description: Searches through list for user determined integer *************************************************************************/ Node *searchListInt(List *pList, int searchOption, int num){ Boolean found = FALSE; Node *conductor = pList->pStart; Node *pMem = NULL; while(found == FALSE && conductor != NULL) { switch(searchOption) { case 5: if(num == conductor->numTimesPlayed) { pMem = conductor; } break; case 2: if(num == conductor->rating) { pMem = conductor; } break; } if(!found) { conductor = conductor->pNext; } } return pMem; } /************************************************************************* * Description: Gets string from user to search for **********************************************************************/ char *getSearchString(void) { char str[100]; char *pStr = NULL; _flushall(); printf(" Enter your search term: "); gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); return pStr; } /************************************************************************* * Description: Get integer from user to search for *************************************************************************/ int getSearchInt(void) { int num = 0; printf(" Enter your search term: "); scanf("%d", &num); return num; } /************************************************************************* * Description: Asks user for input to create new node *************************************************************/ Node *createItem(void) { char *pStr; char str[100]; Node *pMem = NULL; _flushall(); pMem = (Node*)malloc(sizeof(Node)); printf(" Enter artist: "); gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); pMem->pArtist = pStr; printf("Enter song title: "); gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); pMem->pSongTitle = pStr; printf("Enter album title: "); gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); pMem->pAlbumTitle = pStr; printf("Enter Genre: "); gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); pMem->pGenre = pStr; printf("Enter song length: "); scanf("%lf", &(pMem->songLength)); printf("Enter number of plays: "); scanf("%d", &(pMem->numTimesPlayed)); printf("Enter rating: "); scanf("%d", &(pMem->rating)); return pMem; } /************************************************************************* * Description: Deletes user determined item from list *************************************************************************/ void deleteItem(List **pList) { char str[100]; Node *conductor = (*pList)->pStart; Boolean found = FALSE; _flushall(); printf("Enter the song title you would like to delete: "); gets(str); while(conductor != NULL && !found) { if(strcmp(conductor->pSongTitle, str) == 0) { found = TRUE; } else { conductor = conductor->pNext; } } if(!found) { printf(" Record not found"); } else { if(conductor->pPrevious == NULL) //If deleting front node { (*pList)->pStart = conductor->pNext; conductor->pNext->pPrevious = NULL; } else if(conductor->pNext == NULL) //If deleting last node { (*pList)->pEnd = conductor->pPrevious; conductor->pPrevious->pNext = NULL; } else { conductor->pPrevious->pNext = conductor->pNext; conductor->pNext->pPrevious = conductor->pPrevious; } free(conductor); } } /************************************************************************* * Description: Edits any part of node (designated by user) ************************************************************************/ void editItem(Node **pItem) { int num = 0; char str[100]; char *pStr = NULL; printf(" Item to edit: "); printNode(*pItem); printf(" Which attribute would you like to edit? "); printf("1. Artist "); printf("2. Song Title "); printf("3. Album Title "); printf("4. Genre "); printf("5. Song Length "); printf("6. Number of Plays "); printf("7. Rating "); num = (1 + getSortingOption()); _flushall(); printf("Enter new field: "); if(num < 5) { gets(str); pStr = (char*)malloc(sizeof(char)*(strlen(str)+1)); strcpy(pStr, str); } switch(num) { case 1: (*pItem)->pArtist = pStr; break; case 2: (*pItem)->pSongTitle = pStr; break; case 3: (*pItem)->pAlbumTitle = pStr; break; case 4: (*pItem)->pGenre = pStr; break; case 5: scanf("%lf", &((*pItem)->songLength)); break; case 6: scanf("%d", &((*pItem)->numTimesPlayed)); break; case 7: scanf("%d", &((*pItem)->rating)); break; } } /************************************************************************* * Description: Changes rating of item *************************************************************************/ void rateItem(Node **pItem) { int num = 0; do { printf(" Enter new rating for song (1 to 5): "); scanf("%d", &num); if(num < 1 || num > 5) { printf("Invalid rating. "); } }while(num < 1 || num > 5); (*pItem)->rating = num; }
Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote