鱼C论坛

 找回密码
 立即注册
查看: 932|回复: 1

[已解决]通讯录,删除部分会出现地址冲突,其余都正常

[复制链接]
发表于 2021-1-9 14:48:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include<winuser.inl>
  2. #include<stdio.h>
  3. #include <cstdlib>
  4. #include<string.h>
  5. void tail_add(struct People** head);

  6. struct People
  7. {
  8.         char name[20];
  9.         char phone[20];
  10.         struct People *next;
  11. };

  12. void getInput(struct People* people,int wether_change_phone = 0)
  13. {
  14.         printf("enter name:");
  15.         scanf_s("%s", people->name, 20);
  16.         if (wether_change_phone == 0)
  17.         {
  18.                 printf("enter phone:");
  19.                 scanf_s("%s", people->phone, 20);
  20.         }
  21.         else
  22.         {
  23.                 printf("enter new phone:");
  24.                 scanf_s("%s", people->phone, 20);
  25.         }
  26. }

  27. void printfInfo(struct People *head)
  28. {
  29.         struct People* people;
  30.         people = head;
  31.         printf("name: %s \n", people->name);
  32.         printf("phone:%s \n", people->phone);
  33. }

  34. void tail_add(struct People** head)
  35. {
  36.         struct People* people,*temp;
  37.         people = (struct People*)(malloc(sizeof(struct People)));  //动态申请结构体

  38.         if (people == NULL)
  39.         {
  40.                 printf("memory failed");
  41.                 exit(1);
  42.         }

  43.         getInput(people,0);

  44.         //找尾节点
  45.         if (*head == NULL)
  46.         {
  47.                 *head = people;
  48.                 people -> next = NULL;
  49.         }
  50.         else
  51.         {
  52.                 temp = *head;
  53.                 while (temp->next != NULL)
  54.                 {
  55.                         temp = temp->next;
  56.                 }
  57.                 temp->next = people;
  58.                 people -> next = NULL;
  59.         }

  60. }

  61. void find(struct People** head,char find_name[])
  62. {
  63.         struct People * people;
  64.         people = *head;
  65.         //判断书否为空链表,为空,直接结束
  66.         if (people == NULL)
  67.         {
  68.                 printf("no contact people!!!!\n");
  69.         }
  70.         else
  71.         {
  72.                 while (people != NULL)
  73.                 {
  74.                         if (!strcmp( people->name, find_name))
  75.                         {
  76.                                 printfInfo(people);
  77.                                 break;
  78.                         }       
  79.                         else
  80.                         {
  81.                                 people = people->next;
  82.                         }
  83.                 }
  84.         }
  85.         //while循环查找是否有符合条件的人或者到达链表的末端,跳出循环,
  86.         //找到相应的人,打印信息
  87. }

  88. void releaseMemory(struct People** head)
  89. {
  90.         struct People* people, * temp;
  91.         people = *head;
  92.         while (people->next != NULL)
  93.         {
  94.                 temp = people;
  95.                 people = people->next;
  96.                 free(temp);
  97.         }
  98. }

  99. void chang_info(struct People** head, char find_name[])
  100. {
  101.         struct People* people;
  102.         people = *head;

  103.         //遍历链表,找到姓名相同的联系人,修改其信息
  104.         if (people == NULL)
  105.         {
  106.                 printf("no contact people!!!!\n");
  107.         }
  108.         else
  109.         {
  110.                 while (people != NULL)
  111.                 {
  112.                         if (!strcmp(people->name, find_name))
  113.                         {
  114.                                 getInput(people, 1);
  115.                                 break;
  116.                         }
  117.                         else
  118.                         {
  119.                                 people = people->next;
  120.                         }
  121.                 }
  122.         }
  123. }

  124. void delete_info(struct People** head, char delete_name[])
  125. {
  126.         struct People* previous, * current;
  127.         //直接给previous赋值null,current赋值头节点,后面就不需要再用中间变量来存储之后,再进行交换地址了
  128.         //current此时就是一个空的结构体,头指针给他之后,他指向了链表的头节点
  129.         current = *head;
  130.         previous = NULL;

  131.         //找到删除值的位置的前后节点的位置
  132.         while (current != NULL && current->name != delete_name)
  133.         {
  134.                 previous = current;
  135.                 current = current->next;
  136.         }

  137.         //改变链表节点的指向,删除节点
  138.         if (previous == NULL)  //空链表,直接将头指针指向他
  139.         {
  140.                 printf("not found anything\n");
  141.         }
  142.         else
  143.         {
  144.                 if (previous == NULL)  //链表只有一个节点
  145.                 {
  146.                         *head = current->next;
  147.                 }
  148.                 else
  149.                 {
  150.                         previous->next = current->next;//前面用的是current 来判断有没有找到要删除的节点的位置,所以删除就是currennt的节点指向下一个
  151.                 }
  152.                 free(current);
  153.         }

  154. }

  155. void show_all(struct People** head)
  156. {
  157.         struct People* people;
  158.         people = *head;
  159.         printf("all people in the phonebook is:\n");
  160.         while (people != NULL)
  161.         {
  162.                 printfInfo(people);
  163.                 people = people->next;
  164.         }
  165.         printf("\n");
  166.        
  167. }

  168. int main()
  169. {
  170.         printf("---欢迎使用通讯录管理程序--\n");
  171.         printf("---1:插入新的联系人-----\n");
  172.         printf("---2:查找已有的联系人---\n");
  173.         printf("---3更改已有的联系人----\n");
  174.         printf("---4:删除已有的联系人---\n");
  175.         printf("---5:显示当前通讯录----\n");
  176.         printf("---6:显退出当前通讯录---\n");
  177.         printf("\n");

  178.         int order;
  179.         char name[20];
  180.         struct People *phonebook = NULL;
  181.         do
  182.         {
  183.                 printf("请输入指令:\n");
  184.                 scanf_s("%d", &order);
  185.                 switch (order)
  186.                 {
  187.                         case 1:
  188.                                 tail_add(&phonebook);
  189.                                 break;
  190.                         case 2:
  191.                                 printf("enter the name you want to find:\n");
  192.                                 scanf_s("%s",name,20);
  193.                                 find(&phonebook,name);
  194.                                 break;
  195.                         case 3:
  196.                                 printf("enter the name you want to change:\n");
  197.                                 scanf_s("%s", name, 20);
  198.                                 chang_info(&phonebook, name);
  199.                                 break;
  200.                         case 4:
  201.                                 printf("enter the name you want to delete:\n");
  202.                                 scanf_s("%s", name, 20);
  203.                                 delete_info(&phonebook, name);
  204.                                 break;
  205.                         case 5:
  206.                                 show_all(&phonebook);
  207.                                 break;
  208.                         case 6:
  209.                                 printf("退出界面!!1");
  210.                                 exit(1);
  211.                         default:
  212.                                 printf("wrong enter !!!!!!");
  213.                                 break;
  214.                 }
  215.         } while (order != 6);

  216. }
复制代码
最佳答案
2021-1-9 15:56:55
本帖最后由 jackz007 于 2021-1-9 16:13 编辑

        这一句错误
  1.         while (current != NULL && current->name != delete_name)
复制代码

        比较字符串应该通过函数,不能像数值那样直接比。
  1. void delete_info(struct People ** head , char delete_name[])
  2. {
  3.         struct People * previous , * current                                     ;
  4.         printf("\n")                                                             ;
  5.         if(* head) {
  6.                 for(current = previous = * head ; current ; previous = current , current = previous -> next) {
  7.                         if(! strcmp(current -> name , delete_name)) {               // 字符串比较
  8.                                 if(current == previous) * head = current -> next ;  // 在头节点找到
  9.                                 else previous -> next = current -> next          ;  // 在其它节点找到
  10.                                 free(current)                                    ;  // 释放内存
  11.                                 break                                            ;  // 退出循环
  12.                         }
  13.                 }
  14.                 if(current) printf("节点已删除")                                 ;  // 如果找到节点,循环中途退出,current 一定不是 NULL
  15.                 else printf("没有找到节点")                                      ;  // 否则,必然是正常到达循环终点,current 一定是 NULL
  16.         } else {
  17.                 printf("链表为空\n")                                             ;
  18.         }
  19.         printf("\n")                                                             ;
  20. }
复制代码


        此外,在 main() 中,为什么不把菜单显示纳入循环?如果操作多了,每次输入指令的时候,都会看不到菜单,还得靠 "盲人摸象"?
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-1-9 15:56:55 | 显示全部楼层    本楼为最佳答案   
本帖最后由 jackz007 于 2021-1-9 16:13 编辑

        这一句错误
  1.         while (current != NULL && current->name != delete_name)
复制代码

        比较字符串应该通过函数,不能像数值那样直接比。
  1. void delete_info(struct People ** head , char delete_name[])
  2. {
  3.         struct People * previous , * current                                     ;
  4.         printf("\n")                                                             ;
  5.         if(* head) {
  6.                 for(current = previous = * head ; current ; previous = current , current = previous -> next) {
  7.                         if(! strcmp(current -> name , delete_name)) {               // 字符串比较
  8.                                 if(current == previous) * head = current -> next ;  // 在头节点找到
  9.                                 else previous -> next = current -> next          ;  // 在其它节点找到
  10.                                 free(current)                                    ;  // 释放内存
  11.                                 break                                            ;  // 退出循环
  12.                         }
  13.                 }
  14.                 if(current) printf("节点已删除")                                 ;  // 如果找到节点,循环中途退出,current 一定不是 NULL
  15.                 else printf("没有找到节点")                                      ;  // 否则,必然是正常到达循环终点,current 一定是 NULL
  16.         } else {
  17.                 printf("链表为空\n")                                             ;
  18.         }
  19.         printf("\n")                                                             ;
  20. }
复制代码


        此外,在 main() 中,为什么不把菜单显示纳入循环?如果操作多了,每次输入指令的时候,都会看不到菜单,还得靠 "盲人摸象"?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-3 05:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表