0

I am trying to print out the results of the linked list in the reverse order that they were entered in. The program takes 3 inputs, Song name, song length (in seconds) and copyright. The program should take the list of songs and print the in the reverse order that they were entered in.

I am not too familiar with linked list. This is my first time using it as sort of a database.

#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable:4996)

//defining struct
typedef struct node
{
char songName[20];
int songLength;
int copyright;
struct node * next;
}node;

//defining prototypes
node *create(int n);
void display(node *head);


int main()
{
    int n = 0;

    node *head = NULL;

    printf("How many entries?\n");
    scanf("%d", &n);

    //call to create list
    head = create(n);

    printf("\nThe linked list in order is:\n");
    display(head);

return 0;
}

node *create(int n)
{
node *head = NULL;
node *temp = NULL;
node *p = NULL;

for (int i = 0; i < n; i++)
{
    temp = (node*)malloc(sizeof(node));
    printf("What is the name of song %d\n", i + 1);
    //fgets(temp->songName, 20, stdin);
    scanf("%s", &temp->songName);

    printf("What is the length of song %d (in seconds)?\n", i + 1);
    scanf("%d", &temp->songLength);

    printf("Is song %d copyrighted?(1 = YES, 0 = NO)\n", i + 1);
    scanf("%d", &temp->copyright);

    temp->next = NULL;

    if (head == NULL)
    {
        head = temp;
    }
    else
    {
        // if not empty, attach new node at the end
        p = head;

        while (p->next != NULL)
        {
            p = p->next;
        }
        p->next = temp;
    }
}
return head;
}

void display(node *head)
{
    node *p = NULL;

    if (head == NULL)
    {
        printf("List is empty\n");
    }
    else
    {
            p = head;
        while (p != NULL)
        {
        printf("Song: %s, ", p->songName);
        printf("%d minutes, ", p->songLength);
        if (p->copyright == 1)
        {
            printf("Copyrighted\n");
        }
        else if (p->copyright == 0)
        {
            printf("No copyright\n");
        }
            p = p->next;
    }
}
}

So if Input the following:

Song 1 - All Star (song name), 237 (seconds), 0 (no copyrights)

song 2 - Crab Rave, 193, 0

song 3 - 7 rings, 185, 1(copyrights)

The output should be:

7 rings, 185, 1

Crab Rave, 193, 0

All Star, 237, 0

Samiorga
  • 11
  • 6
  • 1
    I would note that this line is wrong: `scanf("%s", &temp->songName);`, and should have generated a compiler warning. I think this is correct: `scanf("%s", temp->songName);`, as `temp->songName` is already the address that you want to pass into `scanf`, – bruceg Jan 30 '19 at 01:04
  • @bruceg at the top of the file I used #pragma disable(warning:4996) I've had the problem where it wouldn't compile because of the warning. I was told to disable the warning – Samiorga Jan 30 '19 at 02:39
  • 1
    Ignoring and disabling warnings is rarely a good idea. – bruceg Jan 30 '19 at 02:52
  • @bruceg My professor just said to add it. Never really gave us a valid reason why to add it. They just said that visual studio is dumb and annoying to use. – Samiorga Jan 30 '19 at 03:02
  • 1
    OMG.... That's extremely bad advice! `gcc` compiler warnings are almost always valid. I haven't used visual studio in a while, but I wouldn't doubt that they're good too. – bruceg Jan 30 '19 at 18:22
  • @bruceg I would normally write scanf as scanf_s because it would let me use it safely. But my professor says to overwrite the safety and disable the safety. – Samiorga Jan 30 '19 at 20:38

1 Answers1

4

If you have a single (forward) linked list, the probably easiest way to print it in reverse order is using recursion:

void display_recursive(node *n) {
    if (!n) {
      return;
    }
    display_recursive(n->next);
    printf("Song: %s, ", n->songName);
    ...
}

Recursion means that a function is calling itself (until some end-condition, the anchor, is reached). By that way, program flow will build up a "stack" of display_recursive- function calls, with the first node, then the second node, ..., until it reaches the last node; by then, recursion stops, and the print part of display_recursive is handled, starting with the last node backwards.

Hope this explanation helps; Try it out in the debugger to see what happens.

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
  • There's also the option to make a backwards link too, but I like this much better. –  Jan 29 '19 at 23:40
  • Can someone explain this recursion to me? I am having trouble understanding why display_recursive is calling display_recursive when its already in the function – Samiorga Jan 29 '19 at 23:44
  • 1
    @SamuelIorga Note that if you move the recursive call to `display_recursive` to _after_ the `printf` calls, you will get printing from head-to-tail (i.e. the _forward_ list). Because the recursive call is made _before_ the `printf`, the nodes are printed in _reverse_ order. As an alternative to `gdb`, you could wrap the recursive call in two debug `printf` calls: `printf("BEF: n=%p next=%p\n",n,n->next); display_recursive(n->next); printf("AFT: n=%p next=%p\n",n,n->next);` You could do this for either the forward or reverse version. It may help with your understanding. – Craig Estey Jan 30 '19 at 00:00