Program: Playlist (C) You will be building a linked list. Make sure to keep trac
ID: 3906038 • Letter: P
Question
Program: Playlist (C)
You will be building a linked list. Make sure to keep track of both the head and tail nodes.
(1) Create three files to submit.
Playlist.h - Struct definition and related function declarations
Playlist.c - Related function definitions
main.c - main() function
Build the PlaylistNode class per the following specifications. Note: Some functions can initially be function stubs (empty functions), to be completed in later steps.
Private data members
char uniqueID[50]
char songName[50]
char artistName[50]
int songLength
PlaylistNode* nextNodePtr
Related functions
CreatePlaylistNode() (1 pt)
InsertPlaylistNodeAfter() (1 pt)
Insert a new node after node
SetNextPlaylistNode() (1 pt)
Set a new node to come after node
GetNextPlaylistNode()
Return location pointed by nextNodePtr
PrintPlaylistNode()
Ex. of PrintPlaylistNode output:
(2) In main(), prompt the user for the title of the playlist. (1 pt)
Ex:
(3) Implement the PrintMenu() function. PrintMenu() takes the playlist title as a parameter and outputs a menu of options to manipulate the playlist. Each option is represented by a single character. Build and output the menu within the function.
If an invalid character is entered, continue to prompt for a valid choice. Hint: Implement Quit before implementing other options. Call PrintMenu() in the main() function. Continue to execute the menu until the user enters q to Quit. (3 pts)
Ex:
(4) Implement "Output full playlist" menu option. If the list is empty, output: Playlist is empty (3 pts)
Ex:
(5) Implement the "Add song" menu item. New additions are added to the end of the list. (2 pts)
Ex:
(6) Implement the "Remove song" function. Prompt the user for the unique ID of the song to be removed.(4 pts)
Ex:
(7) Implement the "Change position of song" menu option. Prompt the user for the current position of the song and the desired new position. Valid new positions are 1 - n (the number of nodes). If the user enters a new position that is less than 1, move the node to the position 1 (the head). If the user enters a new position greater than n, move the node to position n (the tail). 6 cases will be tested:
Moving the head node (1 pt)
Moving the tail node (1 pt)
Moving a node to the head (1 pt)
Moving a node to the tail (1 pt)
Moving a node up the list (1 pt)
Moving a node down the list (1 pt)
Ex:
(8) Implement the "Output songs by specific artist" menu option. Prompt the user for the artist's name, and output the node's information, starting with the node's current position. (2 pt)
Ex:
(9) Implement the "Output total time of playlist" menu option. Output the sum of the time of the playlist's songs (in seconds). (2 pts)
Ex:
Explanation / Answer
Below is your code.
Playlist.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct PlaylistNode_struct {
char uniqueID[50];
char songName[50];
char artistName[50];
int songLength;
struct PlaylistNode_struct* nextNodePtr;
} PlaylistNode;
// Constructor
void CreatePlaylistNode
(PlaylistNode* thisNode, char* uniqueID, char* songName, char* artistName, int songLength, PlaylistNode* nextLoc);
/* Insert newNode after node.
Before: thisNode -- next
After: thisNode -- newNode -- next
*/
void InsertPlaylistNodeAfter
(PlaylistNode* thisNode, PlaylistNode* newNode);
//Set a new node to come after node see test 7
void SetNextPlaylistNode(PlaylistNode* thisNode, PlaylistNode* newNode);
// Print data
void PrintPlaylistNode(PlaylistNode* thisNode);
// Grab location pointed by nextNodePtr
PlaylistNode* GetNextPlaylistNode(PlaylistNode* thisNode);
PlayList.c
#include "Playlist.h"
char inputUniqueID[50];
char inputSongName[50];
char inputArtistName[50];
int inputSongLength = 0;
bool foundNode = false;
void PrintMenuHeader(char* title)
{ printf("%s PLAYLIST MENU ", title);
printf("a - Add song ");
printf("r - Remove song ");
printf("c - Change position of song ");
printf("s - Output songs by specific artist ");
printf("t - Output total time of playlist (in seconds) ");
printf("o - Output full playlist ");
printf("q - Quit ");
}
void PrintMenu(char* title)
{
PlaylistNode* headObj = NULL; // Create PlaylistNode objects
PlaylistNode* currObj = NULL;
PlaylistNode* lastObj = NULL;
PlaylistNode* thisIsTheNode = NULL; //pointer to the node being moved
PlaylistNode* wasBeforeTheNode = NULL;
PlaylistNode* wasAfterTheNode = NULL; //pointer to the next position
PlaylistNode* theNewBefore = NULL; //node pointing to the new position
PlaylistNode* theNewAfter = NULL; //what comes after
int songNumber = 0;
int position = 0;
int newPosition = 0;
//int countUpTo = 0;
if (headObj == NULL){
headObj = (PlaylistNode*)malloc(sizeof(PlaylistNode)); // Front of nodes list
CreatePlaylistNode(headObj, "", "", "", 0, NULL) ;
lastObj = headObj;
} //DO NOT STORE REAL DATA HERE!
PrintMenuHeader(title);
char c = '';
// char name[100];
while (c != 'q')
{
printf("Choose an option: ");
scanf(" %c", &c);
switch (c)
{
case 'a' :
printf("ADD SONG ");
printf("Enter song's unique ID: ");
scanf(" %100[^ ]", inputUniqueID);
printf("Enter song's name: ");
scanf(" %100[^ ]", inputSongName);
printf("Enter artist's name: ");
scanf(" %100[^ ]", inputArtistName);
printf("Enter song's length (in seconds): ");
scanf("%d", &inputSongLength);
if (headObj == NULL){
headObj = (PlaylistNode*)malloc(sizeof(PlaylistNode)); // Front of nodes list
CreatePlaylistNode(headObj, "", "", "", 0, NULL) ;
lastObj = headObj;
} //DO NOT STORE REAL DATA HERE!
else {
currObj = (PlaylistNode*)malloc(sizeof(PlaylistNode));
CreatePlaylistNode(currObj, inputUniqueID, inputSongName, inputArtistName, inputSongLength , NULL);
InsertPlaylistNodeAfter(lastObj, currObj); // Append curr
lastObj = currObj; // Curr is the new last item
}
PrintMenuHeader(title);
break;
case 'r' :
printf("REMOVE SONG ");
printf("Enter song's unique ID: ");
scanf(" %50[^ ]", inputUniqueID);
currObj = headObj;
lastObj = NULL;
do {
if (strcmp(currObj->uniqueID, inputUniqueID) == 0) { //found it
foundNode = true;
lastObj->nextNodePtr = currObj->nextNodePtr;
printf(""%s" removed. ", currObj->songName);
free(currObj);
}
else { //go to the next node
lastObj = currObj;
currObj = currObj->nextNodePtr;
}
} while ((foundNode == false) && (currObj != NULL));
foundNode = false;
PrintMenuHeader(title);
break;
case 'c' :
printf("CHANGE POSITION OF SONG ");
printf("Enter song's current position: ");
scanf("%d", &position);
printf("Enter new position for song: ");
scanf("%d", &newPosition);
lastObj = headObj;
currObj = headObj->nextNodePtr;
songNumber = 1;
while (currObj->nextNodePtr != NULL) {
if (songNumber == position){
wasBeforeTheNode = lastObj;
thisIsTheNode = currObj; //pointer to node that is moving
wasAfterTheNode = currObj->nextNodePtr;
}
if ((position > newPosition) && (songNumber == newPosition - 1)) { //the node before its new place
theNewBefore = currObj;
theNewAfter = currObj->nextNodePtr;
}
if ((position < newPosition) && (songNumber == newPosition)) { //where the node will go
theNewBefore = currObj;
if (currObj->nextNodePtr != NULL) {
theNewAfter = currObj->nextNodePtr;
}
}
lastObj = currObj;
currObj = currObj->nextNodePtr;
songNumber++;
}
thisIsTheNode->nextNodePtr = theNewAfter; // moved here 20170729-0653
theNewBefore->nextNodePtr = thisIsTheNode;
// from here 20170729-0653
wasBeforeTheNode->nextNodePtr = wasAfterTheNode;
printf(""%s" moved to position %d ", thisIsTheNode->songName, newPosition);
PrintMenuHeader(title);
break;
case 's' :
printf("OUTPUT SONGS BY SPECIFIC ARTIST ");
printf("Enter artist's name: ");
scanf(" %50[^ ]", inputArtistName);
currObj = headObj;
songNumber = 1;
while (currObj != NULL) {
if (strcmp(inputArtistName, currObj->artistName) == 0) {
printf("%d. ", songNumber);
PrintPlaylistNode(currObj);
}
currObj = GetNextPlaylistNode(currObj);
songNumber++;
}
break;
case 't' :
printf("OUTPUT TOTAL TIME OF PLAYLIST (IN SECONDS) ");
int sum = 0;
currObj = headObj;
//lastObj = NULL;
while (currObj != NULL) {
sum += currObj->songLength;
currObj = GetNextPlaylistNode(currObj);
}
printf("Total time: %d seconds ", sum);
break;
case 'o' :
printf("%s - OUTPUT FULL PLAYLIST ", title);
if(headObj->nextNodePtr == NULL) {
printf("Playlist is empty ");
}
else{
currObj = headObj->nextNodePtr;
songNumber = 1;
while (currObj != NULL) {
printf("%d. ", songNumber);
PrintPlaylistNode(currObj);
currObj = GetNextPlaylistNode(currObj);
songNumber++;
}
}
PrintMenuHeader(title);
break;
}
}
}
// Constructor yes
void CreatePlaylistNode (PlaylistNode* thisNode, char* uniqueID, char* songName, char* artistName, int songLength, PlaylistNode* nextLoc) {
strcpy(thisNode->uniqueID, uniqueID);
strcpy(thisNode->songName, songName);
strcpy(thisNode->artistName, artistName);
thisNode->songLength = songLength;
thisNode->nextNodePtr = nextLoc;
return;
}
//yes
void InsertPlaylistNodeAfter
(PlaylistNode* thisNode, PlaylistNode* newNode) {
PlaylistNode* tmpNext = NULL;
tmpNext = thisNode->nextNodePtr;
// Remember next
thisNode->nextNodePtr = newNode; // this -- new -- ?
newNode->nextNodePtr = tmpNext; // this -- new -- next
return;
}
//no
void SetNextPlaylistNode(PlaylistNode* thisNode, PlaylistNode* newNode) { //Set a new node to come after node (1 pt)
thisNode->nextNodePtr = newNode;
return;
}
// Print data yes
void PrintPlaylistNode(PlaylistNode* thisNode) {
printf("Unique ID: %s ",thisNode->uniqueID);
printf("Song Name: %s ",thisNode->songName);
printf("Artist Name: %s ",thisNode->artistName);
printf("Song Length (in seconds): %d ", thisNode->songLength);
printf(" ");
return;
}
// Grab location pointed by nextNodePtr
PlaylistNode* GetNextPlaylistNode(PlaylistNode* thisNode) {
return thisNode->nextNodePtr;
}
main.c
#include "Playlist.c"
char playlistTitle[50] = "";
void PrintMenu(char* title);
int main(void) {
printf("Enter playlist's title: ");
scanf(" %100[^ ]", playlistTitle);
PrintMenu(playlistTitle);
return 0;
}
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.