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

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 integers

Explanation / 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);