Home > Enterprise >  Problem with Displaying, Printing in between and deleting in correct position (linked List)
Problem with Displaying, Printing in between and deleting in correct position (linked List)

Time:06-03

While trying to add and print in the linked list the code stops after inbetween. And when it does run (after deleting some function) the deleting and inbetween si not in the defined position.

#include <stdio.h>
#include <stdlib.h>
struct FlavorList{
    char name[100];
    struct FlavorList* next ; 
};
void addAtfront(struct FlavorList **head){
    struct FlavorList *new_cake = (struct FlavorList*)malloc(sizeof(struct FlavorList));
    printf("First cake: ");
    scanf("%s",new_cake->name);
    new_cake->next = *head ; 
    *head = new_cake ; 
}
void addAtback(struct FlavorList **head){
    struct FlavorList* new_cake = (struct FlavorList*) malloc(sizeof(struct FlavorList)); 
    printf("Second cake : ");
    scanf("%s",new_cake->name);
    new_cake->next = NULL;
    struct FlavorList *last = *head;  
    if (*head == NULL)    {
       *head = new_cake;
       return;    
} 
    while (last->next != NULL)
        last = last->next;
    last->next = new_cake;
    return;   
}
void addInbetween(struct FlavorList  ** head , int pos){
    struct FlavorList * new_cake = (struct FlavorList *) malloc(sizeof(struct FlavorList ));
    printf("Between cake : ");
    scanf("%s",new_cake->name);
    new_cake->next = NULL;
    struct FlavorList  *zig = *head ; 
    int count = 0 ; 
    while(zig!=NULL && count<=pos){
        count    ; 
        zig=zig->next ; 
    }
    new_cake->next = zig->next ; 
    zig->next = new_cake ; 
}
void delete(struct FlavorList **head, int pos){
    struct FlavorList*current=*head;
    struct FlavorList*previous=*head;
    if(head ==NULL)    {
        printf("List is empty");
    }
    else if (pos==1)    {
        *head=current->next;
        free(current);
        current=NULL;
    }
    else    {
        while(pos!=1)        {
            previous=current;
            current=current->next;
            pos--;
        }
        previous->next=NULL;
        free(current);
        current=NULL;
    }
}
void display(struct FlavorList  **head){
    struct FlavorList  *zig = * head ;
    while(zig != NULL){
        printf("List of cakes");
        printf("%s",zig->name);
        printf(" ");
        zig=zig->next; 
    }
    printf("\n");
}
int main(){
    struct FlavorList *head = NULL ; 
    printf("--------------------------------\n");
    printf("-----------Cake Shop------------\n");
    printf("--------------------------------\n");
    addAtfront(&head);
    addAtback(&head);
    addInbetween(&head,2);
    display(&head);
    printf("Deleting cake at position 1: \n");
    delete(&head,1);
    printf("Present of now:\n");
    display(&head);
}

Output I get.

--------------------------------
-----------Cake Shop------------
--------------------------------
First cake: First
Second cake : Second
Between cake : Between


...Program finished with exit code 0
Press ENTER to exit console.

When I add one more of addatfront and addatback I can get to the display and the delete part but they are not in the defined positions. The output afterwards:

--------------------------------
-----------Cake Shop------------
--------------------------------
First cake: First1
First cake: First2
Second cake : Second1
Second cake : Second2
Between cake : Middle
List of cakes
First2
First1
Second1
Second2
Middle

Deleting cake at position 1: 
Present of now:
List of cakes
First1
Second1
Second2
Middle

CodePudding user response:

So here is the way I have approached your code. I will be completing and explaining this answer but just so that you have something to look at I will give the whole code

MAX_NAME_SIZE

This macro will allow you to quickly change the maximum allowed size for the name parameter.

Changes to the Linked List:

Let's start with the way I have changed your struct, I have converted it to a typedef so it will be easier to do allocations (this way we don't have to type struct each time) and I have allowed any size to be given to the name parameter.

Sentinel

Now the more important change that will allow you to simply the code even further. Here is a wiki page to learn what it is Sentinel, but to put it simply,is serves as the head node, that contains a value that we never want to read and therefore allowing to pass the head as a simple pointer and not a double pointer!

err.h

I have added this header to allow for a more clean way to manage error exceptions, like for example when the index at which you want to delete a node is out of range.

Free the linked list

I have implemented a simple free function that will free your linked list once you have done all the needed operations with it, otherwise we will be facing a memory leak!


    #include <stdio.h>
    #include <stdlib.h>
    #include <err.h>
    
    #define MAX_NAME_SIZE 100
    
    typedef struct FlavorList
    {
        char *name;
        struct FlavorList *next;
    }FlavorList;
    
    FlavorList * FlavorListBuildSentinel()
    {
        FlavorList *cake_sentinel = malloc(sizeof(FlavorList));
        cake_sentinel->name = malloc(sizeof(char));
        cake_sentinel->next = NULL;
        return cake_sentinel;
    }
    
    void addAtfront(FlavorList *head)
    {
        printf("Adding a new cake in the front!\n");
        char * new_name = malloc(sizeof(char)*(MAX_NAME_SIZE 1));
        scanf("%s",new_name);
        FlavorList *new_cake = malloc(sizeof(FlavorList));
        new_cake->name = new_name;
        new_cake->next = head->next;
        head->next = new_cake;
    }
    
    
    void addAtback(FlavorList *head)
    {
        printf("Adding a new cake in the back!\n");
        FlavorList *new_cake = malloc(sizeof(FlavorList));
        while(head->next!=NULL)
        {
            head = head->next;
        }
        char * new_name = malloc(sizeof(char)*(MAX_NAME_SIZE 1));
        scanf("%s",new_name);
        new_cake->name = new_name;
        new_cake->next = head->next;
        head->next = new_cake;
    }
    
    void addInbetween(FlavorList *head,int pos)
    {
        printf("Adding a new cake at pos: %d!\n",pos);
        while(pos && head->next!=NULL)
        {
            head = head->next;
            pos--;
        }
        //If the pos is still not 0 and the list is out of range, we quit!
        if(pos!=0)
        {
            errx(1, "Index out of range!");
        }
        //If not do the insertion
        FlavorList *new_cake = malloc(sizeof(FlavorList));
        char * new_name = malloc(sizeof(char)*(MAX_NAME_SIZE 1));
        scanf("%s",new_name);
        new_cake->name = new_name;
        new_cake->next = head->next;
        head->next = new_cake;
    }
    
    void delete(FlavorList *head, int pos)
    {
        while(pos && head->next!=NULL)
        {
            head = head->next;
            pos--;
        }
        //If the pos is still not 0 and the list is out of range, we quit!
        if(pos!=0 || head->next == NULL)
        {
            errx(1, "Index out of range!");
        }
        FlavorList * tmp = head->next;
        if(head->next->next!=NULL)
        {
            head->next = head->next->next;
        }
        else
        {
            head->next = NULL;
        }
        free(tmp->name);
        free(tmp);
    }
    
    
    void display(FlavorList* head)
    {
       printf("List of cake names\n");
       int cpt = 1;
       while(head->next)
       {
           head = head->next;
           printf("Cake name at position: %d is %s\n",cpt,(head->name));
           cpt  ;
       }
       printf("\n");
    }
    
    //Frees the allocated node
    void FlavorListFree(FlavorList* head)
    {
        FlavorList* previous;
        while (head)
        {
            previous = head;
            head = head->next;
            free(previous->name);
            free(previous);
        }
    }
    
    
    int main()
    {
        FlavorList * head = FlavorListBuildSentinel();
    
        printf("--------------------------------\n");
        printf("-----------Cake Shop------------\n");
        printf("--------------------------------\n");
        addAtfront(head);
        addAtback(head);
        addInbetween(head,2);
        display(head);
        printf("Deleting cake at position 1: \n");
        delete(head,1);
        printf("Present of now:\n");
        display(head);
        FlavorListFree(head);
    }

I have tested all the functions as well as edge cases and exceptions, and they work just fine, please don't hesitate to ask any questions! Best Regards,

  • Related