Question

I added a "search" function for my linked list menu and I don't know what is wrong in my code. When I enter a search key which is a name that is not in the list, instead of printing the "Search Key: %s Not Found!", the program will just stop. How to fix it? Any suggestion on how can I improve my program?

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

 struct list
    {
char name[20];
int age;
char gender[10];
     struct list *next;
     };

   void main(void)
   {
      struct list *HEAD = NULL;
         struct list *temp,*current, *trav;
        struct list *prev,*temp1,*temp2;

       char choice;


while(1)
{
    clrscr();
    printf("MENU\n");
    printf("A) ADD\n");
    printf("B) DISPLAY\n");
    printf("C) DELETE\n");
    printf("D) SEARCH\n");
    printf("X) EXIT\n");

    scanf("%c", &choice);
    switch(toupper(choice))
{
 case 'A':
            temp= (struct list*)malloc(sizeof(struct list));
            temp->next=NULL;
            printf("Fill-Up the following:\n");
            printf("Name:");
            fflush(stdin);
            gets(temp->name);
            printf("Age:");
            fflush(stdin);
            scanf("%d",&temp->age);
            printf("Gender:");
            fflush(stdin);
            gets(temp->gender);


            if(HEAD == NULL)
            {
                      HEAD = temp;

            }
            else if(HEAD!=NULL)
            {
              for(trav=HEAD; trav->next != NULL; trav= trav->next);
              trav->next=temp;
            }
            else
            {
            printf("Not Enough Memory!\n");
            }

 break;
 case 'B':

          if(HEAD==NULL)
          {
          printf("Linked List is Empty!\n");
          getch();
          }
          else{
          for(trav=HEAD; trav != NULL; trav=trav->next )
          {

                printf("\nName: %s\n", trav->name);
                printf("Age: %d\n", trav->age);
                printf("Gender: %s\n\n", trav->gender);
                     }
                     getch();

          }

 break;

case 'C' :
    temp1=( struct list*)malloc(sizeof(struct list));
    temp1->next=NULL;
    if(HEAD==NULL)
    {
    printf("No item to be delete. List is Empty!\n");
    getch();
        }
    else {
        printf("Enter The Name of the item you want to Delete: ");
        fflush(stdin);
        gets(temp1->name);
        current=HEAD;

        if(strcmp(temp1->name,current->name)== 0)
        {
            HEAD=HEAD->next;
            free(current);
            printf("Item has been successfully deleted from the list.\n");
            getch();
            }
        else
         {
            for(prev=HEAD,trav=HEAD->next; strcmp(trav->name,temp1->name) == 1 ; trav=trav->next,prev=prev->next);

                  if(trav==NULL)
                  {
                  printf("Name: %s not found!", temp1->name);
                  getch();
                  }
                  else{
                prev->next=trav->next;
                free(trav);
                printf("Item has been successfully deleted from the list.\n");
                getch();
                }

            }
        }

    break;
 case 'D':
        temp2=( struct list*)malloc(sizeof(struct list));
    temp2->next=NULL;
        if(HEAD==NULL)
        {
         printf("No item to search. List is Empty.\n");
         getch();
        }
        else{
                printf("Enter Name (Search Key): ");
                fflush(stdin);
                gets(temp2->name);

                int count=0;

                       struct list *trav2=HEAD;
                    while( trav2 !=NULL)
                     {
                       for(struct list *trav1=trav2; strcmp(trav1->name,temp2->name)!=0;trav1=trav1->next);
                           if(trav1!=NULL)
                            {
                    printf("\nName: %s\n", trav1->name);
                    printf("Age: %d\n", trav1->age);
                    printf("Gender: %s\n",trav1->gender);
                    trav2=trav1->next;
                    count++;
                             }
                    else {
                        trav2=NULL;
                        }
                    }
                    getch();
                        if(count==0)
                        {   
                            printf("Search Key: %s Not Found!\n", temp2->name);
                                getch();
                                    }
        }   

 break;
 case 'X':
 if(HEAD!=NULL){free(HEAD); }
if(trav!=NULL){ free(trav); } 
    if(trav1!=NULL){ free(trav1); } 
     if(trav2!=NULL){ free(trav2); } 
   if(temp!=NULL){ free(temp); } 
   if(temp1!=NULL){ free(temp1); } 
 exit(1);

 break;

}

}
}
Was it helpful?

Solution

In your search routine..

for(struct list *trav1=trav2; strcmp(trav1->name,temp2->name)!=0;trav1=trav1->next);

here trav1 will be null at the end of list but you are still going ahead and derefrencing it. Add a check temp1 in your for loop like this:

 for(struct list *trav1=trav2; trav1 && (strcmp(trav1->name,temp2->name)!=0);trav1=trav1->next);

Or, for better readability:

 for (struct list *trav1 = trav2; trav1 != NULL; trav1 = trav1->next)
 {
     if (strcmp(trav1->name, temp2->name) !=0 )
         break;
 }

A few other comments on your code:

  1. Do not use fflush(stdin) use something like this since that is not guaranteed by the standard to work.

    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
    
  2. Stop using gets(). It is impossible to use gets() safely. Use fgets() instead (but be aware it keeps the newline where gets() discards it).

OTHER TIPS

Your loop continues while while( trav2 !=NULL). But where do you set trav2 = trav2->next? Without that, you loop will just continue forever.

But your code seems to have more problems than just that. Why are you allocating a new list item? Just declare a pointer to a list item (struct list*) and then point it to the head of your list.

for (temp = HEAD; temp != NULL; temp = temp->next)
{
    // Examine temp for the value you are looking for
}

I suspect you are still new to understanding pointers. That is key to getting this code working right.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top