Alex
Alex

Reputation: 2299

Issue when comparing a value in a linked list in C

I'm working on a "simple" program in C, where we create a linked list with a structure that acts as a movie which stores, a title, year it was made, rating (1-5), and a pointer to the next node. We are not allowed to add anything to this structure, or define functions.

On top of that, we (for some reason) are required to write the entire linked list in the body of main(), so that adds a certain layer of spaghetti to the problem. Anyways, in this program, we are supposed to have the user enter either 'U' for update or 'S' for search for a movie. The update does what you would expect, you enter a title, year, rating. From this, we are supposed to insert the node at the end of the linked list.

Our search should iterate through this linked list and if it finds a match, should print out the movie, title, and year.

Although the update part of my code works, I can't seem to get search to work. I'm using a movie struct called temp, that starts at head and iterates through the list in an attempt to find the movie. After running some tests through printf, I'm finding that temp is just a null node no matter what, and no matter what movies I enter.

I am assuming this has something to do with the way I'm calling malloc? Or something to do with not assigning nodes correctly? I'm honestly not sure, and unfortunately, the lab's TA had no idea what was wrong either D:

Here is my code:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct movie_node {
        char title[250];
        int year;
        unsigned char rating;
        struct movie_node *next;
};

typedef struct movie_node movie;

int main() {

        // variables
        int loop = 1;
        movie *head = NULL; // represents first
        movie *current; // represents the last node
        movie *temp; // used for traversing the linked list
        head = malloc(sizeof(movie));
        int amountOfMovies = 0; // increment after each addition
        char choice; // either 'u' (update) or 's' (search)
        // ask user for input
        while(loop) {

                printf("%d Movie(s) in the database. Update or search (U/S): ", amountOfMovies);
                scanf(" %c", &choice);
                /* CHOICE 1, UPDATE */
                if(choice == 'U') {

                        // case 1, head is null, we must create a new node
                        if(head == NULL) {
                                // get input
                                printf("Name of the movie: ");
                                scanf(" %[^\n]%*c", head->title);
                                printf("Year: ");
          scanf("%d", &head->year);
                                printf("Rating: ");
                                scanf("%hhu", &head->rating);
                                head->next = NULL;
                                head = current; // set head to point to current
                        } else {
                                current = head;
                                // need to find where current is
                                while(current != NULL) {
                                        current = current->next;
                                } // end while
                                // current is now at the null position, indicating empty node
                                current = malloc(sizeof(movie)); // allocate mem
                                // get user input
                                printf("Name of the movie: ");
                                scanf(" %[^\n]%*c", current->title);
                                printf("Year: ");
                                scanf("%d", &current->year);
                                printf("Rating: ");
                                scanf("%hhu", &current->rating);
                                current->next = NULL;
                        } // end else
                        // output movie
                        printf("Movie \"%s\" is added to the database.\n", current->title);
                        amountOfMovies++; // increment amount of movies in database
                } else if(choice == 'S') {
                /* CHOICE 2, SEARCH */
                        // temp string
                        char tempTitle[250];
                        // flag to let us know if we found something
                        bool found = false;
                        // temp linked list to traverse
                        temp = head;
                        temp = malloc(sizeof(movie));
                        // ask user for input
                        printf("Name of movie: ");
                        scanf(" %[^\n]%*c", tempTitle);
                        printf("NAME OF MOVIE IN HEAD: %s\n", temp->title);             // test, take out later
                        while(temp != NULL) {
                                printf("NAME OF CURRENT MOVIE TO COMPARE TO: %s\n", temp->title); // test
                                if(strcmp(temp->title, tempTitle) == 0) {
                                        // match
                                        printf("Year: %d\n", temp->year);
                                        printf("Rating: %hhu\n", temp->rating);
                                        found = true;
                                        break;
                                } else { // no match so far
                                        temp = temp->next;
                                        printf("HAVEN'T FOUND MATCH, NEXT TITLE TO CHECK IS: %s\n", temp->title); // test print
                                        found = false;
                                }  // end else
                        } // end while
                        if(found == false) { // no match confirmed
                                printf("Movie \"%s\" does not exist in the database.\n", tempTitle);
                        }
                } else { // choice is invalid
                        loop = 0; // exit
                } // end if-else

        } // end while
        // free all the nodes

        return 0;
}

Note: the only thing I haven't implemented yet is freeing the memory.. which I'm not a hundred percent sure how I should accomplish it.

Any help is greatly appreciated..

Upvotes: 0

Views: 1380

Answers (2)

BLUEPIXY
BLUEPIXY

Reputation: 40145

sample to fix

movie *new_node(void){//aggregate the creation of a new node
    movie *node = malloc(sizeof(*node));//error check omit
    printf("Name of the movie: ");
    scanf(" %249[^\n]%*c", node->title);
    printf("Year: ");
    scanf("%d", &node->year);
    printf("Rating: ");
    scanf("%hhu", &node->rating);
    node->next = NULL;
    return node; 
}

int main() {
    int loop = 1;
    movie *head = NULL; 
    movie *current; 
    movie *temp; 
    //head = malloc(sizeof(movie));//"if(head == NULL) {" don't work 
    int amountOfMovies = 0; 
    char choice; 

    while(loop) {
        printf("%d Movie(s) in the database. Update or search (U/S): ", amountOfMovies);
        scanf(" %c", &choice);

        if(choice == 'U') {
            if(head == NULL) {
                current = head = new_node();//need set to current
            } else {
                current = head;
                while(current->next != NULL) {//"current != NULL" can't link
                    current = current->next;
                }
                current = current->next = new_node(); 
            } 
            printf("Movie \"%s\" is added to the database.\n", current->title);
            amountOfMovies++; 
        } else if(choice == 'S') {
            char tempTitle[250];
            bool found = false;//need <stdbool.h>
            temp = head;
            //temp = malloc(sizeof(movie));//Unnecessary
            printf("Name of movie: ");
            scanf(" %249[^\n]%*c", tempTitle);
            //printf("NAME OF MOVIE IN HEAD: %s\n", temp->title);            
            while(temp != NULL) {
                //printf("NAME OF CURRENT MOVIE TO COMPARE TO: %s\n", temp->title); 
                if(strcmp(temp->title, tempTitle) == 0) {
                    printf("Year: %d\n", temp->year);
                    printf("Rating: %hhu\n", temp->rating);
                    found = true;
                    break;
                } else { 
                    temp = temp->next;
                    printf("HAVEN'T FOUND MATCH, NEXT TITLE TO CHECK IS: %s\n", temp->title); 
                    //found = false;//Unnecessary
                }  
            } 
            if(found == false) { 
                printf("Movie \"%s\" does not exist in the database.\n", tempTitle);
            }
        } else { 
            loop = 0; 
        } 
    } 
    // free all the nodes
    return 0;
}

Upvotes: 0

syntagma
syntagma

Reputation: 24344

The problem is with your malloc() calls. First you do:

movie *head = NULL;
// ...
head = malloc(sizeof(movie));

This means that head is no longer null and you won't be able to insert first movie the way you want to - move that malloc() somewhere else.

Secondly, few lines of code below, you do:

current = head; // <- this is OK
// ...
current = malloc(sizeof(movie)); // allocate mem <- this is NOT OK, for the same reason as before

Also, you can read titles of the movies like that: scanf("%249s", head->title).

Let me know if you know how to go from there.

Apart from the problems in your code, there is another problem: the lab's TA had no idea what was wrong either.

Upvotes: 0

Related Questions