Home > Back-end >  Deleting a node from linked list
Deleting a node from linked list

Time:12-07

I'm trying to delete nodes given by birth number for example 9403133410. Next time I print the linked list I wanna see only Mike in output.

Here is my file.txt to load into linked list

***
Dave
9403133410
***
Mike
9458133410
***
Dave
9403133410

Here is my struct called node_t:

typedef struct node {
    char                *presenter;
    char                *birth_number;
    struct node         *next;
}node_t;
node_t *node_new(){
    node_t *node = malloc(sizeof(node_t));

    node->next = NULL;
    node->presenter = NULL;
    node->birth_number = NULL;

    return node;
}

Here is my load function

node_t *node_load(const char *file){
    int counter = 0, number_entries = 0, db_loaded = 0;
    char buffer[BUFFER_SIZE];
    dbFile = fopen(DATABASE_FILE, "r");

    if (!dbFile){printf("Zaznamy neboli najdene!\n");}

    node_t *ptr = NULL, *head = NULL;

    while(fgets(buffer, BUFFER_SIZE, dbFile) != NULL){
        switch(counter  ){
        case 0:
            if (!ptr){
                ptr = node_new();
                head = ptr;
            }
            else{
                ptr->next = node_new();
                ptr = ptr->next;
            }
            number_entries  ;
            break;
        case 1:
            ptr->presenter = strdup(buffer);
            break;
        case 2:
            ptr->birth_number = strdup(buffer);
            counter = 0;

            break;
        }
   }
    fclose(dbFile);
    return head;
}

And here is my delete node function:

void node_delete(node_t *head){
    node_t *temp, *previous;
    temp = head;
    char birth_n[14];

    scanf("%s", &birth_n);
    strcat(birth_n, "\n");

    for ( ; temp->next != NULL; temp = temp->next){
        if (strcmp(birth_n, temp->birth_number) == 0){
            if (temp == head){
                head = temp->next;
            }
            else{
                previous = temp;
                previous->next = temp->next;
            }
            free(temp);
        }
    }
}

So what I'm trying is to delete the node given by its birth_number.

Debug function:

void node_delete(node_t *head){
    node_t *temp, *previous;
    previous = temp = head;
    char birth_n[14];

    scanf("%s", &birth_n);

    if (strcmp(birth_n, temp->birth_number) != 0){
        head = head->next;
        free(temp);
    }
}

This function should delete the first node, but its not deleting it...

CodePudding user response:

The function does not make a sense.

Firstly the searched string should be passed to the function through a parameter.

Secondly the function deals with a copy of the value of the pointer to the head node. Changing the copy within the function does not influence on the original pointer used as a function argument.

At least instead of this call

scanf("%s", &birth_n);

you should write

scanf("s", birth_n);

Also it is unclear why you are trying to append the new line character '\n'

strcat(birth_n, "\n");

This for loop

for ( ; temp->next != NULL; temp = temp->next){

can invoke undefined behavior when the passed pointer is a null pointer. Also the loop will be skipped when the list contains only one node even if the node contains the target string.

Moreover the loop is not terminated when a node with the target string was deleted.

And using the pointer temp in the third expression of the loop

temp = temp->next

after this statement

free(temp);

invokes undefined behavior.

The function can look the following way

int node_delete( node_t **head, const char *birth_number )
{
    while ( *head != NULL && strcmp( ( *head )->birth_number, birth_number ) != 0 )
    {
        head = &( *head )->next;
    }

    int success = *head != NULL;

    if ( success )
    {
        node_t *temp = *head;
        *head = ( *head )->next;
        free( temp );
    }

    return success;
}

And in main you have to enter the target string that will be searched and the function is called at least like

node_delete( &head, birth_number );

Also you can check the return value of the function to be sure whether a node with the specified string was deleted.

CodePudding user response:

If you enable compiler warnings and treat warnings as errors, you might see error messages like this:

format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[14]’ [-Werror=format=]
      |     scanf("%s", &birth_n);
      |            ~^   ~~~~~~~~
      |             |   |
      |             |   char (*)[14]
      |             char *

This tells you that the %s format string for scanf is not compatible with what you're feeding it. You're feeding it a pointer to a character pointer, rather than just the character pointer that you clearly intended it to be.

You should have passed just birth_n to the scanf function, like so:

 scanf("%s", birth_n);

This has nothing to do with linked lists, but is basic input and string handling in C.

  • Related