【问题标题】:"search" linked list in cc中的“搜索”链表
【发布时间】:2014-03-29 14:43:11
【问题描述】:

我为我的链表菜单添加了一个“搜索”功能,但我不知道我的代码有什么问题。当我输入一个不在列表中的搜索关键字时,程序将停止打印,而不是打印“搜索关键字:%s Not Found!”。如何解决?关于如何改进我的程序有什么建议吗?

 #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;

}

}
}

【问题讨论】:

  • 构建调试版本,并在调试器中运行。调试器将停在崩溃的位置(很可能是),并允许您检查并向上遍历函数调用堆栈,以及检查变量的值。
  • 代码太长,无法阅读。不过,我敢打赌,您忘记了 gets 命令使您的搜索字符串以返回结尾。
  • 另请注意,技术上fflush(stdin) 是未定义的。有些系统确实允许它作为扩展。
  • 对不起,我是编程新手。
  • 主要建议:将您的程序拆分为独立的函数。单个函数中的代码太多了。你的内存释放代码在我看来很可疑;没有什么会遍历整个链表并依次释放每个节点。

标签: c search linked-list dynamic-allocation


【解决方案1】:

在您的搜索程序中..

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

这里 trav1 将在列表末尾为空,但您仍在继续并取消引用它。 在你的 for 循环中添加一个检查 temp1,如下所示:

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

或者,为了更好的可读性:

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

您的代码中的其他一些 cmets:

  1. 不要使用fflush(stdin) 使用这样的东西,因为标准不能保证它可以工作。

    int c;
    while ((c = getchar()) != EOF && c != '\n')
        ;
    
  2. 停止使用gets()。不可能安全地使用gets()。请改用fgets()(但请注意,它会保留gets() 丢弃它的换行符)。

【讨论】:

  • 请注意,在 Windows 上,MSVC 确实定义了 fflush(stdin) 的行为。但是,在其他平台上,它可能无法满足您的需求。
【解决方案2】:

您的循环在while( trav2 !=NULL) 时继续。但是你在哪里设置trav2 = trav2-&gt;next?没有它,你的循环将永远持续下去。

但您的代码似乎还存在更多问题。你为什么要分配一个新的列表项?只需声明一个指向列表项 (struct list*) 的指针,然后将其指向列表的头部。

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

我怀疑你对指针的理解还是新手。这是让这段代码正常工作的关键。

【讨论】:

  • 我更新了if(trav1!=NULL)trav2=trav1-&gt;next中的trav
猜你喜欢
  • 2013-07-20
  • 2018-04-17
  • 2016-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-21
相关资源
最近更新 更多