• 模拟通讯录(详解通讯录排序qsort,strcmp)


    前言:

            学习了C语言结构体、联合体、枚举等,就可以写一个通讯录来强化自己对结构体的理解学习。顺便提升大家的基本功!!

    通讯录菜单的打印:

            关于菜单的打印在之前写游戏的时候写过多次,大家可以参照之前的改写菜单。

    代码如下:

    1. int main()
    2. {
    3. int input = 0;
    4. do
    5. {
    6. menu();
    7. printf("请输入你的选择:>");
    8. scanf("%d", &input);
    9. switch(input)
    10. {
    11. case 1:
    12. break;
    13. case 2:
    14. break;
    15. case 3:
    16. break;
    17. case 4:
    18. break;
    19. case 5:
    20. break;
    21. case 6:
    22. break;
    23. case 0:
    24. printf("退出通讯录\n");
    25. break;
    26. default:
    27. printf("选择错误,请重新选择\n");
    28. break;
    29. }
    30. } while (input);
    31. return 0;
    32. }
    1. void menu()
    2. {
    3. printf("*********************************\n");
    4. printf("**** 1.add 2.del ********\n");
    5. printf("**** 3.search 4.modify ********\n");
    6. printf("**** 5.show 6.sort ********\n");
    7. printf("**** 0.exit ********\n");
    8. printf("*********************************\n");
    9. }

    关于菜单的打印在这里不再进行强调。

            如果大家在switch的时候选择太多,都是数字不知道是什么意思,此时大家可以利用枚举常量,把这些数字与含义联系到一起。

            EXIT        表示0;

            ADD        表示1;

            DEL        表示2;

            SEARCH 表示 3;

            MODIFY  表示4;

            SHOW    表示5;

             SORT     表示6;        

            代码如下:

            

    1. enum Option
    2. {
    3. EXIT,
    4. ADD,
    5. DEL,
    6. SEARCH,
    7. MODIFY,
    8. SHOW,
    9. SORT,
    10. };
    1. int main()
    2. {
    3. int input = 0;
    4. do
    5. {
    6. menu();
    7. switch (input)
    8. {
    9. case ADD:
    10. break;
    11. case DEL:
    12. break;
    13. case SEARCH:
    14. break;
    15. case MODIFY:
    16. break;
    17. case SHOW:
    18. break;
    19. case SORT:
    20. break;
    21. case EXIT:
    22. break;
    23. default:
    24. break;
    25. }
    26. } while (input);
    27. return 0;
    28. }

    定义并初始化通讯录:

    定义通讯录:

            菜单打印完成后,就需要定义通讯录,并且要将其初始化为0,方便后期增加联系人

    将定义的一些函数或者是量放在.h的头文件中。

    1. #define NAME_MAX 20
    2. #define SEX_MAX 10
    3. #define TELE_MAX 12
    4. #define ADDR_MAX 30
    5. #define MAX 100
    6. //定义一个通讯录
    7. typedef struct PeoInfo
    8. {
    9. char name[NAME_MAX];
    10. int age;
    11. char sex[SEX_MAX];
    12. char tele[TELE_MAX];
    13. char addr[ADDR_MAX];
    14. }PeoInfo;
    15. //定义整个通讯录
    16. typedef struct Contact
    17. {
    18. PeoInfo data[MAX];
    19. int sz;//记录通信录中人的信息个数
    20. }Contact;

    初始化通讯录:

            我们可以再创建一个源文件,在创建好的源文件中初始化。

    1. void InitContaxt(Contact* pc)//初始化通讯录
    2. {
    3. pc->sz = 0;
    4. memset(pc->data, 0, sizeof(pc->data));
    5. }

    这里用到了memset库函数,可以进行对内存块的赋值。

    添加联系人:

            在contact源文件定义addcontact函数,在.h文件中声明。在1.文件中使用。

    代码如下:

                开始前必须判断有没有空间放得下。(用if语句)

    1. void addcontact(Contact* pc)
    2. {
    3. if (pc->sz == MAX)
    4. {
    5. printf("通讯录已满,无法存放\n");
    6. return;
    7. }
    8. printf("请输入联系人姓名:");
    9. scanf("%s",pc->data[pc->sz].name);
    10. printf("请输入联系人年龄:");
    11. scanf("%d", &pc->data[pc->sz].age);
    12. printf("请输入联系人性别:");
    13. scanf("%s", pc->data[pc->sz].sex);
    14. printf("请输入联系人电话:");
    15. scanf("%s", pc->data[pc->sz].tele);
    16. printf("请输入联系人住址:");
    17. scanf("%s", pc->data[pc->sz].addr);
    18. printf("添加成功\n");
    19. pc->sz++;
    20. }

    展示通讯录:

            showcontact函数。

    1. void showcontact(Contact* pc)
    2. {
    3. if (pc->sz == 0)
    4. {
    5. printf("通讯录为空\n");
    6. return;
    7. }
    8. printf("%-20s%-5s%-5s%-20s%-30s\n", "姓名:", "年龄:", "性别:", "电话:", "住址");
    9. int i = 0;
    10. for (i = 0; i < pc->sz; i++)
    11. {
    12. printf("%-20s%-5d%-5s%-20s%-30s\n", pc->data[i].name, pc->data[i].age,
    13. pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
    14. }
    15. }

    删除联系人:

            注意事项:

            1、删除之前需要判断该联系人存不存在!!

            2、删除可以理解为覆盖,用删除的联系人之后的覆盖前面的。

            3、两个字符串比较大小必须用strcmp库函数。

            4、可以把查找联系人存不存在封装成一个函数。

    1. void delcontact(Contact* pc)
    2. {
    3. char name[NAME_MAX];
    4. assert(pc);
    5. printf("请输入你要删除联系人的姓名\n");
    6. scanf("%s",name);
    7. if (pc->sz == 0)
    8. {
    9. printf("通讯录为空,无法删除\n");
    10. return;
    11. }
    12. int ret = Find(pc, name);
    13. if (ret == -1)
    14. {
    15. printf("无法找到该联系人\n");
    16. return;
    17. }
    18. else
    19. {
    20. int i = 0;
    21. for (i = ret; i < pc->sz-1; i++)
    22. {
    23. pc->data[i] = pc->data[i + 1];
    24. }
    25. pc->sz--;
    26. printf("删除成功\n");
    27. }
    28. }

    查找联系人的find函数代码如下:

            

    1. int Find(Contact* pc,char*name)
    2. {
    3. int i = 0;
    4. for (i = 0; i < pc->sz; i++)
    5. {
    6. if (strcmp(pc->data[i].name, name) == 0)
    7. {
    8. return i;
    9. }
    10. }
    11. return -1;
    12. }

    查找联系人:

            searchcontact函数:

    1. void searchcontact(Contact* pc)
    2. {
    3. char name[NAME_MAX];
    4. assert(pc);
    5. printf("请输入你要删除联系人的姓名\n");
    6. scanf("%s", name);
    7. if (pc->sz == 0)
    8. {
    9. printf("通讯录为空,无法查找\n");
    10. return;
    11. }
    12. int ret = Find(pc, name);
    13. if (ret == -1)
    14. {
    15. printf("无法找到该联系人\n");
    16. return;
    17. }
    18. else
    19. {
    20. printf("%-20s%-5s%-5s%-20s%-30s\n", "名字", "年龄", "性别", "电话", "地址");
    21. printf("%-20s%-5d%-5s%-20s%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tele
    22. , pc->data[ret].addr);
    23. printf("查找成功\n");
    24. }
    25. }

    修改联系人信息:

    1. void modifycontact(Contact* pc)
    2. {
    3. char name[NAME_MAX];
    4. assert(pc);
    5. if (pc->sz == 0)
    6. {
    7. printf("通讯录为空,无法修改\n");
    8. return;
    9. }
    10. printf("输入要修改的人的名字:");
    11. scanf("%s", name);
    12. int ret = Find(pc, name);
    13. if (ret == -1)
    14. {
    15. printf("要修改的人不存在\n");
    16. return;
    17. }
    18. printf("输入名字:");
    19. scanf("%s", pc->data[ret].name);
    20. printf("输入年龄:");
    21. scanf("%d", &pc->data[ret].age);
    22. printf("输入性别:");
    23. scanf("%s", pc->data[ret].sex);
    24. printf("输入电话:");
    25. scanf("%s", pc->data[ret].tele);
    26. printf("输入地址:");
    27. scanf("%s", pc->data[ret].addr);
    28. }

    *联系人排序:

    利用strcmp函数冒泡排序:

            要点:

            注意结构体之间的交换。
            注意strcmp函数的使用,如果不懂,可以看写文章-CSDN创作中心中有介绍。

    1. void sortcontact(Contact* pc)
    2. {
    3. assert(pc);
    4. if (pc->sz == 0)
    5. {
    6. printf("通讯录为空,无法排序\n");
    7. return;
    8. }
    9. int i = 0;
    10. for (i = 0; i < pc->sz; i++)
    11. {
    12. int j = 0;
    13. for (j = 0; j < pc ->sz - i-1; j++)
    14. {
    15. if ((strcmp(pc->data[j].name, pc->data[j + 1].name))>0)
    16. {
    17. //交换结构体
    18. PeoInfo a = pc->data[j];
    19. pc->data[j] = pc->data[j + 1];
    20. pc->data[j + 1] = a;
    21. }
    22. }
    23. }
    24. printf("排序成功\n");
    25. }

    利用qsort函数快速排序:

            要点:

            如果想使用qsort函数快速排序,必须熟知qsort函数的使用原理,它的4个参数分别是什么,分别表示什么意思,最好是自己模拟过qsor函数,用起来更加方便!!

            不懂qsort函数的使用可以看C语言指针详解(3)-CSDN博客,里面有相关qsort的介绍和模拟实现。

            代码如下:

            

    1. int compar(const void *p1,const void *p2)
    2. {
    3. return *(char*)p1 - *(char*)p2;
    4. }
    5. void sortcontact(Contact* pc)
    6. {
    7. assert(pc);
    8. if (pc->sz == 0)
    9. {
    10. printf("通讯录为空,无法排序\n");
    11. return;
    12. }
    13. qsort(pc->data->name, pc->sz, sizeof(PeoInfo), compar);
    14. }

    注:用qsort确实简单,但是必须注意qsort的参数分别表示什么含义,注意compar函数的自定义!!

  • 相关阅读:
    不会代码循环断言如何实现?只要6步!
    html、css、js原生的弹窗功能
    引擎入门 | Unity UI简介–第2部分(5)
    人工神经网络教学视频第三版,人工神经网络教程
    【面经】如何查看服务器内存和磁盘空间占用
    【JS逆向系列】某乎x96参数3.0版本与jsvmp进阶
    CI+JUnit5并发单测机制创新实践
    C语言 while循环1
    【从零开始学微服务】03.软件架构的演化过程
    如何制作并运行 jar 程序
  • 原文地址:https://blog.csdn.net/m0_75235246/article/details/139392700