• c语言练习85:通讯录的实现(基于顺序表实现)


    通讯录的实现(基于顺序表实现)

    基于动态顺序表实现通讯录 C语⾔基础要求:结构体、动态内存管理、顺序表、⽂件操作

    1、功能要求

    1)⾄少能够存储100个⼈的通讯信息

    2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等

    3)增加联系⼈信息

    4)删除指定联系⼈

    5)查找制定联系⼈

    6)修改指定联系⼈

    7)显⽰联系⼈信息

    处理方法:

    报错:

    处理方法:

    报错:

    处理方法:

    头文件最上方加#pragma once

    contact.h

    1. #pragma once
    2. #define _CRT_SECURE_NO_WARNINGS
    3. //创建保存联系人数据的结构
    4. #define NAME_MAX 100
    5. #define SEX_MAX 100
    6. #define TEL_MAX 100
    7. #define ADDR_MAX 100
    8. struct ContactInfo
    9. {
    10. char name[NAME_MAX];//使用定长数组还是动态数组?
    11. char sex[SEX_MAX];//字符数组数组名即为数组首元素地址
    12. int age;
    13. char tel[TEL_MAX];
    14. char addr[ADDR_MAX];
    15. };
    16. typedef struct ContactInfo CInfo;
    17. //通讯表的底层是通过顺序表来实现的
    18. typedef struct SeqList contact;
    19. //通讯录的初始化和销毁
    20. void ContactInit(contact* pcon);//
    21. void ContactDistory(contact* pcon);
    22. //添加联系人
    23. void ContactAdd(contact* pcon);
    24. int FindByName(contact* pcon, char* name);
    25. //删除联系人
    26. void ContactDel(contact* pcon);
    27. //修改联系人
    28. void ContactModify(contact* pcon);
    29. //查看联系人
    30. void ContactShow(contact* pcon);
    31. //查找联系人
    32. void ContactFind(contact* pcon);

    Seqlist.h

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include"Contact.h"
    7. //typedef int SLDataType;
    8. typedef struct ContactInfo SLDataType;//更改数据类型为通讯录数据类型
    9. typedef struct SeqList
    10. {
    11. SLDataType* a;
    12. int size;//顺序表中有效的数据格式
    13. int capacity;//顺序表当前的空间大小
    14. }SL;
    15. //typedef struct SeqList SL(即为)
    16. //对顺序表进行初始化
    17. void SLInit(SL* ps);
    18. //对顺序表进行销毁
    19. void SLDestory(SL* ps);
    20. //尾部插入
    21. void SLPushBack(SL* ps, SLDataType x);
    22. //头部插入
    23. void SLPushFront(SL* ps, SLDataType x);
    24. //尾部删除
    25. void SLPopBack(SL* ps);
    26. //头部删除
    27. void SLPopFront(SL* ps);
    28. //打印
    29. void SLPrint(SL* ps);
    30. //判断顺序表是否位空
    31. bool SLIsEmpty(SL* ps);
    32. //在任意位置插入删除
    33. //在指定位置之前插入数据
    34. void SLInsert(SL* ps, int pos, SLDataType x);
    35. //删除指定位置的数据
    36. void SLErase(SL* ps, int pos);
    37. bool SLFind(SL* ps, SLDataType x);
    38. //判断空间是否足够,不够则进行扩容
    39. void SLCheckCapacity(SL* ps);

    contact.c

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include"Contact.h"
    3. #include"SeqList.h"
    4. //通讯录的初始化和销毁
    5. void ContactInit(contact* pcon) {
    6. SLInit(pcon);
    7. }
    8. void ContactDistory(contact* pcon) {
    9. SLDestory(pcon);
    10. }
    11. void ContactAdd(contact* pcon) {
    12. //所有数据都是CInfo里的
    13. CInfo info;
    14. printf("请输入联系人姓名: \n");
    15. scanf("%s", info.name);//数组名即为首地址
    16. printf("请输入联系人姓别: \n");
    17. scanf("%s", info.sex);
    18. printf("请输入联系人年龄: \n");
    19. scanf("%d", &info.age);
    20. printf("请输入联系人电话: \n");
    21. scanf("%s", info.tel);
    22. printf("请输入联系人地址: \n");
    23. scanf("%s", info.addr);
    24. //获取到联系人数据后,其被保存到了结构体info中
    25. //下一步即为往通讯录顺序表中插入数据
    26. SLPushBack(pcon, info);
    27. }
    28. int FindByName(contact* pcon, char* name) {
    29. for (int i = 0; i < pcon->size; i++) {
    30. if (strcmp(pcon->a[i].name, name) == 0) {
    31. return i;
    32. }
    33. }
    34. return -1;
    35. }
    36. //删除联系人
    37. void ContactDel(contact* pcon) {
    38. printf("请输入要删除的用户名称:\n");
    39. char name[NAME_MAX];
    40. scanf("%s", name);
    41. int findindex = FindByName(pcon, name);
    42. if (findindex < 0) {
    43. printf("要删除的用户不存在!\n");
    44. return;
    45. }
    46. //找到了要删除findindex位置的数据
    47. SLErase(pcon, findindex);
    48. }
    49. //修改联系人
    50. void ContactModify(contact* pcon) {
    51. //打印通讯录所有的数据
    52. //先打印表头文字
    53. printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
    54. for (int i = 0; i < pcon->size; i++) {
    55. printf("%-4s %-4s %-4d %-4s %-4s\n",
    56. pcon->a[i].name,
    57. pcon->a[i].sex,
    58. pcon->a[i].age,
    59. pcon->a[i].tel,
    60. pcon->a[i].addr
    61. );
    62. }
    63. }
    64. //查看联系人
    65. void ContactShow(contact* pcon) {
    66. char name[NAME_MAX];
    67. printf("请输入要查找的联系人: \n");
    68. scanf("%s", name);
    69. //获得通讯录(顺序表)下标的位置
    70. int find = FindByName(pcon, name);
    71. if (find < 0) {
    72. printf("要查找的用户不存在!\n");
    73. return;
    74. }
    75. printf("请输入新的用户名称: \n");
    76. scanf("%s", pcon->a[find].name);
    77. printf("请输入新的用户性别: \n");
    78. scanf("%s", pcon->a[find].sex);
    79. printf("请输入新的用户年龄: \n");
    80. scanf("%d", pcon->a[find].age);
    81. printf("请输入新的用户电话: \n");
    82. scanf("%s", pcon->a[find].tel);
    83. printf("请输入新的用户地址: \n");
    84. scanf("%s", pcon->a[find].addr);
    85. printf("修改成功! \n");
    86. }
    87. //查找联系人
    88. void ContactFind(contact* pcon) {
    89. char name [NAME_MAX];
    90. printf("请输入要查找的联系人 \n");
    91. scanf("%s", name);
    92. int find = FindByName(pcon, name);
    93. if(find < 0) {
    94. printf("该联系人不存在! \n");
    95. return;
    96. }
    97. //打印当前联系人
    98. printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "住址");
    99. printf("%-4s %-4s %-4d %-4s %-4s\n",
    100. pcon->a[find].name,
    101. pcon->a[find].sex,
    102. pcon->a[find].age,
    103. pcon->a[find].tel,
    104. pcon->a[find].addr
    105. );
    106. }

    Seqlist.c

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include"SeqList.h"
    3. void SLInit(SL* ps) {
    4. ps->a = NULL;
    5. ps->capacity = ps->size = 0;//也可在初始化时开辟空间
    6. }
    7. void SLDestory(SL* ps) {
    8. if (ps->a) {
    9. free(ps->a);
    10. }
    11. ps->a = NULL;
    12. ps->capacity = ps->size = 0;
    13. }
    14. void SLCheckCapacity(SL* ps) {
    15. //空间足够直接尾插
    16. //空间不够则进行扩容
    17. if (ps->size == ps->capacity) {
    18. //空间不够则进行扩容(relloc申请失败返回空指针)
    19. int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
    20. SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * 2 * sizeof(SLDataType));
    21. if (tmp == NULL) {
    22. perror("relloc fail\n");
    23. return 1;
    24. }
    25. ps->a = tmp;
    26. ps->capacity = newCapacity;
    27. }
    28. }
    29. void SLPushBack(SL* ps, SLDataType x){
    30. assert(ps != NULL);
    31. //空间足够直接尾插
    32. //空间不够则进行扩容(relloc申请失败返回空指针)
    33. SLCheckCapacity(ps);
    34. //直接插入数据
    35. ps->a[ps->size] = x;//ps->a[ps->size++] = x;
    36. ps->size++;
    37. }
    38. void SLPushFront(SL* ps, SLDataType x) {
    39. assert(ps);
    40. //判断空间是否足够不够则扩容
    41. SLCheckCapacity(ps);
    42. for (size_t i = ps->size; i > 0; i--) {
    43. ps->a[i] = ps->a[i - 1];
    44. }
    45. ps->a[0] = x;
    46. ps->size++;
    47. }
    48. void SLPopBack(SL* ps) {
    49. assert(ps);
    50. assert(!SLIsEmpty(ps));//assert(ps->size)也可以
    51. //ps->a[ps->size - 1] = 0;//(可有可无)
    52. ps->size--;//size最初为0,为0则不能减减
    53. }
    54. void SLPopFront(SL* ps, SLDataType x) {
    55. assert(ps);
    56. assert(!SLIsEmpty(ps));//进行判空操作,不为空才能继续
    57. //让后面数据往前挪一位
    58. for (size_t i = 0; i < ps->size-1; i++) {//size_t为无符号整形
    59. //最后一次进来i为ps->size-2
    60. ps->a[i] = ps->a[i + 1];
    61. }
    62. ps->size--;
    63. }
    64. void SLPrint(SL* ps) {
    65. for (size_t i = 0; i < ps->size; i++) {
    66. printf("%d ", ps->a[i]);
    67. }
    68. printf("\n");
    69. }
    70. bool SLIsEmpty(SL* ps) {
    71. assert(ps);
    72. return ps->size == 0;//当前数据表有效数据位0,则当前数据表为空
    73. }
    74. //在指定位置之前插入数据
    75. void SLInsert(SL* ps, int pos, SLDataType x) {
    76. assert(ps);
    77. //对pos加以限制
    78. assert(pos >= 0 && pos <= ps->size);
    79. //扩容
    80. SLCheckCapacity(ps);
    81. //把pos位置及以后的数据往后挪动一位
    82. //循环里i的初始值可以为size或size-1k,但不同的初始值对应不同的结束条件
    83. /*for (size_t i = ps->size; i > pos; i--) {
    84. ps->a[i] = ps->a[i - 1];
    85. }*/
    86. for (size_t i = ps->size-1; i > pos-1; i--) {
    87. ps->a[i+1] = ps->a[i];
    88. }
    89. ps->a[pos] = x;
    90. ps->size++;
    91. }
    92. //删除指定位置的数据
    93. void SLErase(SL* ps, int pos) {
    94. assert(ps);
    95. assert(!SLIsEmpty(ps));//进行判空操作,不为空才能继续
    96. //对pos加以限制
    97. assert(pos >= 0 && pos <= ps->size);
    98. for (int i = pos; i < ps->size - 1; i++) {
    99. //最后一次进来的i的数据为ps->size - 2
    100. ps->a[i] = ps->a[i + 1];
    101. }
    102. ps->size--;
    103. }
    104. //bool SLFind(SL* ps, SLDataType x) {
    105. // assert(ps);
    106. // for (int i = 0; i < ps->size; i++) {
    107. // if (ps->a[i] == x) {
    108. // 找到了
    109. // return true;
    110. // }
    111. // }
    112. // return false;
    113. //}

    test.c

    1. #define _CRT_SECURE_NO_WARNINGS
    2. #include"SeqList.h"
    3. #include"Contact.h"
    4. //void SLtest() {
    5. // SL sl;
    6. // SLInit(&sl);
    7. // //尾部插入
    8. // SLPushBack(&sl, 1);
    9. // SLPushBack(&sl, 2);
    10. // SLPushBack(&sl, 3);
    11. // SLPushBack(&sl, 4);
    12. // SLPrint(&sl);
    13. // //头部插入
    14. // SLPushFront(&sl, 5);
    15. // SLPushFront(&sl, 6);
    16. // SLPushFront(&sl, 7);
    17. // SLPrint(&sl);
    18. // SLPopBack(&sl);
    19. // SLPrint(&sl);
    20. // SLPopBack(&sl);
    21. // SLPrint(&sl);
    22. // SLDestory(&sl);
    23. //}
    24. //void SLtest02() {
    25. // SL sl;
    26. // SLInit(&sl);
    27. // //尾部插入
    28. // SLPushBack(&sl, 1);
    29. // SLPushBack(&sl, 2);
    30. // SLPushBack(&sl, 3);
    31. // SLPushBack(&sl, 4);
    32. // SLPrint(&sl);
    33. // 头删
    34. // //SLPopFront(&sl);
    35. // //SLPrint(&sl);
    36. // //SLPopFront(&sl);
    37. // //SLPrint(&sl);
    38. // //SLDestory(&sl);
    39. // //在指定位置之前插入数据
    40. // /*SLInsert(&sl, 1, 11);
    41. // SLPrint(&sl);
    42. // SLDestory(&sl);*/
    43. // 删除指定位置的数据
    44. // //SLErase(&sl, 0);
    45. // //SLPrint(&sl);
    46. // //SLErase(&sl, sl.size-1);
    47. // //SLPrint(&sl);
    48. // //
    49. // bool findRet=SLFind(&sl, 3);
    50. // if (findRet) {
    51. // printf("找到了\n");
    52. // }
    53. // else {
    54. // printf("没有找到!\n");
    55. // }
    56. // SLDestory(&sl);
    57. //void contact01() {
    58. // contact con;
    59. // ContactInit(&con);
    60. // //往通讯录中插入数据
    61. // ContactAdd(&con);
    62. // ContactDistory(&con);
    63. // }
    64. //}
    65. void menu()
    66. {
    67. printf("***************通讯录**************\n");
    68. printf("****1> 添加联系人 2>删除联系人*****\n");
    69. printf("****3> 修改联系人 4>查找联系人*****\n");
    70. printf("****5> 查看通讯录 0>退出 *****\n");
    71. printf("**********************************\n");
    72. }
    73. int main() {
    74. //SLtest();
    75. //SLtest02();
    76. /*contact01();*/
    77. contact con;
    78. int op = -1;
    79. ContactInit(&con);
    80. do {
    81. menu();
    82. printf("请输入您的操作:> \n");
    83. scanf("%d", &op);
    84. switch (op) {
    85. case 1:
    86. ContactAdd(&con);
    87. break;
    88. case 2:
    89. ContactDel(&con);
    90. break;
    91. case 3:
    92. ContactModify(&con);
    93. break;
    94. case 4:
    95. ContactFind(&con);
    96. break;
    97. case 5:
    98. ContactShow(&con);
    99. break;
    100. case 0:
    101. printf("~BYE~\n");
    102. break;
    103. }
    104. } while (op != 0);
    105. ContactDistory(&con);
    106. return 0;
    107. }

  • 相关阅读:
    读取.nrrd和.dcm文件格式医学图片可视化与预处理
    时序分解 | Matlab实现EEMD集合经验模态分解时间序列信号分解
    C语言新手写函数中出现数组时运行bug的解决
    qt笔记一
    appium ios webview
    玩转 MaxCompute SQL 训练营! 数据分析挖掘迅速出师
    javascript基础学习大纲梳理
    由SoftRefLRUPolicyMSPerMB=0引起的频繁Full GC问题排查实战
    如何利用ChatGPT提升学术论文写作效率
    浏览器原理之跨域?跨站?你真的不懂我!
  • 原文地址:https://blog.csdn.net/2301_77479435/article/details/133778006