C program need help, plz give me a new answer but not copy others Many of us hav
ID: 3880743 • Letter: C
Question
C program need help, plz give me a new answer but not copy others
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 manipulate our music collection based on attributes such as artist, album title, song title, genre, song length, number times played, and rating. For this assignment you will write a basic digital music manager (DMM) Your DMM program must have a text-based interface which allows the user to select from a main menu of options including: (1) load, (2) store, (3) display, (4) insert, (5) delete, (6) edit, (7) sort, (8) rate, (9) play, (10) shuffle, and 11) exit. For Part I of the assignment, you will only need to complete the main menu, 1) load, (2) store, (3) display, (6) edit, (8) rate, (9) play, and (11) exit features. The other features will be completed in the next part of the assignment What must the main menu contain? The main menu must display the following commands: (1) load (2) store (3) display (4) insert (5) delete (6) edit (7) sort (8) rate (9) play (10) shuffle (11) exit After a command is selected and completed, your program must display the main menu again. This procedure will continue until the "exit" command is selected what must “load" do? The "load" command must read all records from a file called musicPlayList.csv (you may find a sample file here) into a dynamic doubly linked list. The doubly linked list is considered the main playlist. As each record is read from the file, it must be inserted at the front of the list. Each record consists of the following attributes Artist a string Album title - a string Song title- a string Genre - a string Song length-a struct Duration type consisting of seconds and minutes, both integersExplanation / Answer
main.c
--------------------------------------------------------
#include <conio.h>
#include "dmm.h"
int main()
{
Node* pHead = NULL;
Node* pMem = NULL;
int userCommand = 0;
int success = 0;
while (userCommand != 11)//menu only terminates at option 11
{
system("cls");
printf("What would you like to do? Please enter a number. "
"(1) load "
"(2) store "
"(3) display "
"(4) insert "
"(5) delete "
"(6) edit "
"(7) sort "
"(8) rate "
"(9) play "
"(10) shuffle "
"(11) exit ");
userCommand = menuPrompt(11);
if (!pHead && (userCommand != 1) )
{
userCommand = 1;
printf("No songs loaded. Attempting to load songs first. ");
}
switch (userCommand)
{
case 1: //load
pHead = load();
if (pHead)
printf("Songs Loaded. ");
else
printf("No songs Loaded. Ensure musicPlayList.csv "
"in local memory.");
printf(" Press any key to continue...");
getch();
break;
case 2: //store
store(pHead);
printf("Songs stored. Press any key to continue.");
getch();
break;
case 3: //display
display(pHead);
break;
case 4: //insert
success = insertFront(&pHead, NULL);
if (success)
printf("Song added to library. Press any key to continue...");
break;
case 5: //deleteNode
printf("Choose a song to delete. ");
pMem = search(pHead);
deleteNode(&pHead, pMem);
break;
case 6: //edit
printf("Choose a song to edit. ");
pMem = search(pHead);
editRecord(pMem, 0);
break;
case 7: //sort
sort(pHead);
printf("Records sorted. Here is new order. ");
printList(pHead);
printf(" Press any key to continue...");
getch();
break;
case 8: //rate
printf("Choose a song to rate. ");
pMem = search(pHead);
rate(pMem);
break;
case 9: //play
printf("Choose a song to start playing at. ");
pMem = search(pHead);
play(pMem);
break;
case 10: //shuffle
shuffle(pHead);
printf("Press any key to continue...");
getch();
break;
case 11: //exit
printf("Saving Music Library and exiting. ");
store(pHead);
break;
default:
break;
}
}
return 1;
}
------------------------------------------------------------------------------------------------
dmm.c
----------------------------------------------------
#include "dmm.h"
Node *makeNode(char *line)
{
Node *pMem = NULL;
pMem = (Node*)malloc(sizeof(Node));
if (pMem)
{
pMem->pNext = NULL;
pMem->pPrev = NULL;
if (line)
fillRecord(line, pMem);
else
editRecord(&pMem->data, 1);
}
return pMem;
}
int insertFront(Node** pHead, char* line)
{
int success = 0;
Node *pMem = NULL;
pMem = makeNode(line);
if (pMem)
{
success = 1;
if (*pHead == NULL) // dealing with an empty list
{
(*pHead) = pMem;
}
else // not dealing with empty list
{
pMem->pNext = *pHead;
(*pHead)->pPrev = pMem;
*pHead = pMem;
}
}
return success;
}
void fillDuration(char *time, Node* thisNode)
{
Duration* editDuration = &thisNode->data.songLength;
char timeCopy[50] = " ";
strcpy(timeCopy, time);
editDuration->minutes = atoi(strtok(timeCopy, ":"));
editDuration->seconds = atoi(strtok(NULL, ":"));
}
char* durationToString(Node* thisNode)
{
Duration *time = &thisNode->data.songLength;
char durationString[50] = " ";
sprintf(durationString, "%d:%02d", time->minutes, time->seconds);
return durationString;
}
void fillRecord(char *line, Node* thisNode)
{
Record* newRecord = &thisNode->data;
char timeTemp[7] = "00:00";
char artist[100] = """;
char lineCopy[800] = " ";
strcpy(lineCopy, line);
if (lineCopy[0] == '"')//Check for quotated artist
{
strcat(artist, strtok(lineCopy, """));
strcat(artist, """);
}
else//artist not in quotations, go straight to tokenizing with comma
strcpy(artist, strtok(lineCopy, ","));
strcpy(newRecord->artist, artist);
strcpy(newRecord->albumTitle, strtok(NULL, ","));
strcpy(newRecord->songTitle, strtok(NULL, ","));
strcpy(newRecord->genre, strtok(NULL, ","));
strcpy(timeTemp, strtok(NULL, ","));
newRecord->playCount = atoi(strtok(NULL, ","));
newRecord->rating = atoi(strtok(NULL, ","));
fillDuration(timeTemp, thisNode);
}
void editRecord(Node* thisNode, int newRecord)
{
char userInput[100] = " ";
int userCommand = 0;
int index = 0;
Record * recordEdit = &thisNode->data;
int safeness = 0; //this int is used to screen for bad user input
if (newRecord == 1) //skip prompt and set all fields if new record
userCommand = 8;
else
{
printf(" What field of the record would you like to edit? "
"(1) Artist "
"(2) Album Title "
"(3) Song Title "
"(4) Genre "
"(5) Song Length "
"(6) Play Count "
"(7) Rating "
"(8) All fields ");
userCommand = menuPrompt(8);
}
switch (userCommand)
{
case 1:
case 8://artist
while (safeness == 0) // don't let user proceed until input good
{
safeness = 1;
printf("What would you like to set the artist to? ");
gets(userInput);
//check for commas that will affect formatting in csv file
for (index = 0; userInput[index]; index++)
if (userInput[index] == ',')
safeness = 0;
//if quotations around artist formatting okay
if (userInput[0] == '"' &&
userInput[strlen(userInput) - 1] == '"')
safeness = 1;
//check for an empty string to avoid 2 commas next to each other
else if (userInput[0] == '')
safeness = 0;
//if string isn't safe let the user know and prompt again.
if (safeness == 0)
printf("If your entry contains commas it must be contained "
"in quotes. Must also not be empty. ");
}
strcpy(recordEdit->artist, userInput);
printf("Artist changed to: %s ", recordEdit->artist);
printf("Press any key to continue... ");
getch();
safeness = 0;
if (userCommand != 8)
break;
case 2://album title
while (safeness == 0)
{
printf("What would you like to set the album title to? ");
gets(userInput);
safeness = screen(userInput);
}
strcpy(recordEdit->albumTitle, userInput);
printf("Album title changed to: %s ", recordEdit->albumTitle);
printf("Press any key to continue... ");
getch();
safeness = 0;
if (userCommand != 8)
break;
case 3: //song title
while (safeness == 0)
{
printf("What would you like to set the song title to? ");
gets(userInput);
safeness = screen(userInput);
}
strcpy(recordEdit->songTitle, userInput);
printf("Song title changed to: %s ", recordEdit->songTitle);
printf("Press any key to continue... ");
safeness = 0;
if (userCommand != 8)
break;
case 4: //genre
while (safeness == 0)
{
printf("What would you like to set the genre to? ");
gets(userInput);
safeness = screen(userInput);
}
strcpy(recordEdit->genre, userInput);
printf("Genre set to: %s ", recordEdit->genre);
printf("Press any key to continue... ");
getch();
if (userCommand != 8)
break;
case 5: //song length
printf("Setting time. ");
printf("How many minutes in this song? " //get minutes
"I won't believe it if you say more than 32766. ");
recordEdit->songLength.minutes = menuPrompt(32766);
printf("How many seconds in this song? " //get seconds
"the number of seconds must be less than 60. ");
recordEdit->songLength.seconds = menuPrompt(59);
strcpy(userInput, durationToString(recordEdit));
printf("Duration of song set to: %s ", userInput);
printf("Press any key to continue... ");
getch();
if (userCommand != 8)
break;
case 6: //play count
printf("How many times have you listened to this song? "
"I won't believe it if you say more than 32766. ");
recordEdit->playCount = menuPrompt(32766);
printf("Play count set to: %d ", recordEdit->playCount);
printf("Press any key to continue... ");
getch();
if (userCommand != 8)
break;
case 7:
rate(recordEdit);
if (userCommand != 8)
break;
default:
break;
}
}
char* recordToString(Node* thisNode)
{
Record * songInfo = &thisNode->data;
char recordString[200] = " ";
char time[7] = " ";
strcpy(time, durationToString(songInfo));
//Format the string with commas in between fields
sprintf(recordString, "%s,%s,%s,%s,%s,%d,%d ", songInfo->artist,
songInfo->albumTitle, songInfo->songTitle, songInfo->genre,
time, songInfo->playCount, songInfo->rating);
return recordString;
}
Node* load()
{
FILE *infile = fopen("musicPlayList.csv", "r"); //open file
char line[200] =" "; //store lines pulled from file
fgets(line, 200, infile);
Node *pHead = makeNode(line);
while(fgets(line, 200, infile))
insertFront(&pHead, line);
fclose(infile);//close file
return pHead;
}
// gives user option to display all records or all songs
// from one artist.
void display(Node* pHead)
{
int userCommand = 0;
printf("Display: 1. All records 2. Search for a Record ");
userCommand = menuPrompt(2);
if (userCommand == 1)
{
printList(pHead);
printf(" These are all your songs. Press any key to continue...");
getch();
}
else
search(pHead);
}
void store(Node* pHead)
{
char line[200] = " ";
FILE *outfile = fopen("musicPlayList.csv", "w");
while (pHead->pNext) //traverse to tail of list
pHead = pHead->pNext;
while (pHead) //store lines of data while traversing to head of list
{
strcpy(line, recordToString(&pHead->data));
fprintf(outfile, "%s", line);
pHead = pHead->pPrev;
}
fclose(outfile);
}
void printList(Node *pHead)
{
char line[200] = " ";
Node* pCur = pHead;
while (pCur->pNext) //traverse to tail of list
pCur = pCur->pNext;
while (pCur) //print while traversing to head
{
strcpy(line, recordToString(pCur));
printf(line);
pCur = pCur->pPrev;
}
}
Node* search(Node *pHead)
{
char* pSearchField = NULL;
size_t addressOffset = 0;
Node* results[100] = { '' }; //holds search results
char userInput[100]= " ";
char temp[100] = " ";
int index = 0;
int menuIndex = 0;
int userCommand = 0;
printf(" What field would you like to search by? "
"(1) Artist "
"(2) Album Title "
"(3) Song Title "
"(4) Genre ");
userCommand = menuPrompt(4);
//calculate offset of field that user wants to search by
for (int i = 1; i < userCommand; i++)
addressOffset += sizeof(char[100]);
userCommand = 0; //reset menu selection to 0
printf(" Enter search criteria: "); //get search string
gets(userInput);
while (pHead) //search through list from head to tail
{
//set pointer to relevant field of struct by offsetting
pSearchField = (char*)&pHead->data + addressOffset;
//pSearchField = (char*)(pSearchField + addressOffset);
//copy string from record and check for matches with user input
strcpy(temp, pSearchField);
if (contains(temp, userInput))
{
results[menuIndex] = pHead; //store match in array
menuIndex++;
}
pHead = pHead->pNext;
}
//Display results
if (menuIndex == 0)//no results found
{
printf("No Matches Found. Press any key to continue ");
getch();
}
else if (menuIndex == 1)//1 result found
{
strcpy(temp, recordToString(results[0]));
printf("Found 1 result: ");
printf("%s ", temp);
printf("Press any key to continue ");
getch();
}
else //multiple results found
{
printf("Found %d results: ", (menuIndex));
while (results[index])
{
strcpy(temp, recordToString(results[index]));
printf("%d. %s ", index + 1, temp);
index++;
}
printf("Choose a song."); //prompt user to choose a result
userCommand = menuPrompt(index + 1) - 1; // subtract 1 for array index
strcpy(temp, recordToString(results[userCommand]));
printf("%s Press any key to continue... ", temp);
getch();
}
return(results[userCommand]);
}
int deleteNode(Node** pHead, Node* pDelete)
{
int success = 0;
if (pDelete)//something there to delete
{
success = 1;
if (*pHead == pDelete) //head of list
*pHead = pDelete->pNext;
if (pDelete->pNext)//not tail of list
pDelete->pNext->pPrev = pDelete->pPrev;
if (pDelete->pPrev) // Not head of list
pDelete->pPrev->pNext = pDelete->pNext;
free(pDelete);
}
return success;
}
void sort(Node *pHead)
{
int i = 0, j = 0;
int userCommand = 0;
Node* pSorted = pHead;
Node* pCur = pHead;
Record tempData = pHead->data;
char* pTextField = NULL;
char* pNextTextField = NULL;
char textField[100] = " ";
char nextTextField[100] = " ";
unsigned int* pIntField = 0;
unsigned int* pNextIntField = 0;
size_t addressOffset = 0;
printf(" What field would you like to sort by? "
"(1) Artist "
"(2) Album Title "
"(3) Song Title "
"(4) Genre "
"(5) Play Count "
"(6) Rating ");
userCommand = menuPrompt(6);
//calculate offset of pointer based on user selection.
for (int i = 1; i < userCommand; i++)
{
if (i <= 4)
addressOffset += sizeof(char[100]);
else
addressOffset += sizeof(unsigned int);
}
//sorting by text field
if (userCommand <= 4)
{
while (pSorted->pNext)
pSorted = pSorted->pNext; //traverse to end of list
while (pSorted->pPrev)
{
pCur = pHead;
while (pCur != pSorted)
{
//find pertinent fields in Record structs with offset
pTextField = (char*)&pCur->data + addressOffset;
pNextTextField = (char*)&pCur->pNext->data + addressOffset;
//make copies of strings
strcpy(textField, pTextField);
strcpy(nextTextField, pNextTextField);
//set copies to lower case
while (textField[j])
{
textField[j] = tolower(textField[j]);
j++;
}
j = 0;
while (nextTextField[j])
{
nextTextField[j] = tolower(nextTextField[j]);
j++;
}
j = 0;
//compare copies
if (strcmp(textField, nextTextField) < 0)
{
tempData = pCur->data;
pCur->data = pCur->pNext->data;
pCur->pNext->data = tempData;
}
pCur = pCur->pNext;
}
pSorted = pSorted->pPrev;
}
}
else //sorting by int field
{
while (pSorted->pNext)
pSorted = pSorted->pNext;
while (pSorted->pPrev)
{
pCur = pHead;
while (pCur != pSorted)
{
//find pertinent fields in Record structs with offset
pIntField = (char*)(&pCur->data) + addressOffset;
pNextIntField = (char*)(&pCur->pNext->data) + addressOffset;
//compare int fields
if (userCommand == 5) //descending for play count
{
if (*pIntField > *pNextIntField)
{
tempData = pCur->data;
pCur->data = pCur->pNext->data;
pCur->pNext->data = tempData;
}
}
else //ascending for rating
{
if (*pIntField < *pNextIntField)
{
tempData = pCur->data;
pCur->data = pCur->pNext->data;
pCur->pNext->data = tempData;
}
}
pCur = pCur->pNext;
}
pSorted = pSorted->pPrev;
}
}
}
void shuffle(Node* pHead)
{
Node* pCur = pHead;
int success = 1;
int itinerary = 0, nodeCounter = 0, listPosition = 0, listDestination = 0;
int i = 0, j = 0, random = 0, temp = 0;
int* shuffler = NULL;
char playDisplay[500] = " ";
while (pCur->pNext)
{
pCur = pCur->pNext;
nodeCounter++;
listPosition++;
}
shuffler = (int*)malloc(sizeof(int) * (nodeCounter+1));
if (!shuffler) //check for failure allocating memory
success = 0;
else
{
success = 1;
//fill shuffler array
for (i = 0; i <= nodeCounter; i++)
{
*(shuffler + i) = i;
}
//swap every position with a random other position
for (i = 0; i <= nodeCounter; i++)
{
random = rand() % nodeCounter;
temp = *(shuffler + i);
*(shuffler + i) = *(shuffler + random);
*(shuffler + random) = temp;
}
//traverse to positions dictated by array
for (i = 0; i <= nodeCounter; i++)
{
listDestination = *(shuffler + i);
itinerary = listDestination - listPosition;
if (itinerary < 0)
{
for (j = 0; j > itinerary; j--)
{
pCur = pCur->pPrev;
listPosition--;
}
}
else
{
for (j = 0; j < itinerary; j++)
{
pCur = pCur->pNext;
listPosition++;
}
}
strcpy(playDisplay, recordToString(&pCur->data));
printf("Playing: %s ", playDisplay);
Sleep(500);
}
}
}
void play(Node* playFrom)
{
char playDisplay[200] = " ";
while (playFrom)
{
strcpy(playDisplay, recordToString(&playFrom->data));
printf("Playing: %s ", playDisplay);
Sleep(500);
playFrom = playFrom->pNext;
}
}
void rate(Node* thisNode)
{
Record* pEdit = &thisNode->data;
printf("What is your rating for this song from 1 - 5? ");
pEdit->rating = menuPrompt(5);
printf("Rating changed to: %d/5", pEdit->rating);
}
unsigned int menuPrompt(int numOptions)
{
char userInput[100] = " ";
int menuEntry = 0;
while (menuEntry > numOptions || menuEntry <= 0)
{
printf("Answer with a number: ");
gets(userInput);
menuEntry = atoi(userInput);
if (menuEntry > numOptions || menuEntry <= 0)
printf("invalid entry. ");
}
system("cls");
return (menuEntry);
}
int screen(char* userInput)
{
int safeness = 1;
int index = 0;
if (userInput[0] == '')
safeness = 0;
while (userInput[index])
{
if(userInput[index] == ',')
safeness = 0;
index++;
}
if(safeness == 0)
printf("Entry may not contain commas and must have something in it.");
return safeness;
}
int contains(char* string, char* substring)
{
int contains = 0;
int index = 0;
while (string[index])
{
string[index] = tolower(string[index]);
index++;
}
index = 0;//reset index for different use
while (substring[index])
{
substring[index] = tolower(substring[index]);
index++;
}
index = 0;//reset index for different use
//look for substrings of userInput in artist field at current record
if (strstr(string, substring))
contains = 1;
return contains;
}
--------------------------------------------------------------------------------------------
dmm.h
------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
typedef struct duration
{
unsigned int minutes;
unsigned int seconds;
}Duration;
typedef struct record
{
char artist[100];
char albumTitle[100];
char songTitle[100];
char genre[100];
unsigned int playCount;
unsigned int rating;
Duration songLength;
}Record;
typedef struct node
{
Record data;
struct node *pPrev;
struct node *pNext;
}Node;
Node *makeNode(char *song);
int insertFront(Node** pHead, char* song);
void fillDuration(char *time, Duration *pMem);
char* durationToString(Record* thisRecord);
void fillRecord(char *line, Node *newNode);
void editRecord(Record* recordEdit, int newRecord);
char* recordToString(Node *thisNode);
Node* load();
void display(Node *pHead);
void store(Node *pHead);
void printList(Node *pHead);
Node* search(Node *pHead);
int deleteNode(Node** pHead, Node* pDelete);
void sort(Node *pHead);
void shuffle(Node* pHead);
void play(Node* playFrom);
void rate(Record* song);
int screen(char* userInput);
int contains(char* string, char* substring);
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.