• c语言小课设--通讯录(动态内存管理)


    前言:

    在没学动态内存管理之前,我们用的结构体,数组等都是静态分配内存的,也就是说数组的长度是固定的,但是这并不满足我们的实际需求,所以在通讯录项目里面我就用到了动态内存分布。简单来说,就是当需要储存的联系人数据太多了的时候,我们就可以扩大一点空间用来存放新的数据,也就是说实现了要多少,就开辟多少的空间。

    项目介绍:

    该项目实现一个通讯录功能,除了能根据具体需求扩大空间之外,也实现了最基本基本的增删查改等功能,并在退出通讯录时销毁创造的空间,从而不造成内存泄露。

    另外,这个项目由三部分组成,函数功能的实现在Contact.c源文件中,各种头文件、函数等声明则由文件Contact.h来实现,最后测试在源文件test.c文件中进行。

    一、teat.c文件:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include"Contact.h"
    3. enum Option {
    4. Exit,
    5. add,
    6. modify,
    7. del,
    8. search,
    9. show,
    10. sort
    11. };
    12. void menu() {
    13. printf("************************\n");
    14. printf("**1.添加 2.修改******\n");
    15. printf("**3.删除 4.搜索******\n");
    16. printf("**5.展示 6.排序******\n");
    17. printf("**0.退出 ******\n");
    18. printf("************************\n");
    19. }
    20. int main() {
    21. int input = 0;
    22. Contacts Con;
    23. Init(&Con);
    24. do {
    25. menu();
    26. printf("请输入你的选择--》\n");
    27. scanf("%d", &input);
    28. switch (input) {
    29. case add://添加
    30. Add_Peo(&Con);
    31. break;
    32. case modify://修改
    33. Modify_Peo(&Con);
    34. break;
    35. case del:
    36. Del_Peo(&Con);
    37. break;
    38. case search:
    39. Sear_Peo(&Con);
    40. break;
    41. case show:
    42. Show_Peo(&Con);
    43. break;
    44. case sort:
    45. Sort_Peo(&Con);
    46. break;
    47. case Exit:
    48. SaveContact(&Con);
    49. Destory_Contacts(&Con);
    50. printf("退出通讯录\n");
    51. break;
    52. default:
    53. printf("你的输入有误!\n");
    54. break;
    55. }
    56. } while (input != 0);
    57. return 0;
    58. }

    二、Contact.h头文件:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define name_max 20
    7. #define sex_max 5
    8. #define tele_max 12
    9. #define addr_max 20
    10. #define num_max 100
    11. #define default_cap 3
    12. typedef struct PeoInfo {
    13. char name[name_max];
    14. char sex[sex_max];
    15. char tele[tele_max];
    16. int age;
    17. }PeoInfo;
    18. //静态通讯录版本
    19. //typedef struct Contacts {
    20. // PeoInfo data[num_max];
    21. // int sz;
    22. //}Contacts;
    23. //动态版本
    24. typedef struct Contacts {
    25. PeoInfo *data;//存放数据
    26. int sz;//记录当前联系人的数量
    27. int cap;//当前通讯录的容量
    28. }Contacts;
    29. //初始化通讯录
    30. void Init(Contacts* Con);
    31. //添加功能
    32. void Add_Peo(Contacts* Con);
    33. //修改功能
    34. void Modify_Peo(Contacts* Con);
    35. //删除联系人
    36. void Del_Peo(Contacts* Con);
    37. //展示联系人
    38. void Show_Peo(Contacts* Con);
    39. //查询联系人
    40. void Sear_Peo(Contacts* Con);
    41. //排序
    42. void Sort_Peo(Contacts* Con);
    43. //保存数据到通讯录中
    44. void SaveContact(Contacts* Con);
    45. //加载信息到通讯录
    46. void LoadContact(Contacts* Con);

    三、Contact.c文件:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include"Contact.h"
    3. // 自定义比较剂,按名字字典序排序
    4. int cmp(void* e1,void *e2) {
    5. //printf("%s %s\n", (, ((struct PeoInfo*)e2)->name);
    6. return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
    7. }
    8. //初始化通讯录
    9. void Init(Contacts* Con) {
    10. assert(Con);
    11. Con->sz = 0;
    12. Con->cap = default_cap;
    13. Con->data = calloc(Con->cap, sizeof(PeoInfo));
    14. if (Con->data == NULL) {
    15. printf("初始化失败\n");
    16. return;
    17. }
    18. LoadContact(Con);
    19. }
    20. //void Init(Contacts* Con) {
    21. // assert(Con);
    22. // Con->sz = 0;
    23. // memset(Con->data, 0, sizeof(Con->data));
    24. //}
    25. //增加容量
    26. void check_cap(Contacts* Con) {
    27. PeoInfo* ptr = realloc(Con->data, (Con->cap + 2) * sizeof(PeoInfo));
    28. if (ptr != NULL) {
    29. Con->data = ptr;
    30. Con->cap += 2;
    31. printf("增容成功\n");
    32. }
    33. else {
    34. perror("AddContacts->realloc");
    35. return;
    36. }
    37. }
    38. //添加功能
    39. //动态版本
    40. void Add_Peo(Contacts* Con) {
    41. assert(Con);
    42. if (Con->sz == Con->cap) {
    43. check_cap(Con);
    44. }
    45. printf("请输入添加人的姓名\n");
    46. scanf("%s", Con->data[Con->sz].name);
    47. printf("请输入添加人的年龄\n");
    48. scanf("%d", &Con->data[Con->sz].age);
    49. printf("请输入添加人的性别\n");
    50. scanf("%s", Con->data[Con->sz].sex);
    51. printf("请输入添加人的号码\n");
    52. scanf("%s", Con->data[Con->sz].tele);
    53. Con->sz++;
    54. return;
    55. }
    56. //静态版本
    57. //void Add_Peo(Contacts* Con) {
    58. // assert(Con);
    59. // if (Con->sz == num_max) {
    60. // printf("通讯录已满\n");
    61. // return;
    62. // }
    63. // else {
    64. // printf("请输入添加人的姓名\n");
    65. // scanf("%s", Con->data[Con->sz].name);
    66. // printf("请输入添加人的年龄\n");
    67. // scanf("%d", &Con->data[Con->sz].age);
    68. // printf("请输入添加人的性别\n");
    69. // scanf("%s", Con->data[Con->sz].sex);
    70. // printf("请输入添加人的号码\n");
    71. // scanf("%s", Con->data[Con->sz].tele);
    72. // Con->sz++;
    73. // return;
    74. // }
    75. //}
    76. //按名字查找
    77. int find_name(Contacts* Con,char *tager) {
    78. assert(Con);
    79. for (int i = 0; i < Con->sz; i++) {
    80. if (strcmp(Con->data[i].name, tager)==0) {
    81. return i;
    82. }
    83. }
    84. return -1;
    85. }
    86. //修改功能
    87. void Modify_Peo(Contacts* Con) {
    88. assert(Con);
    89. char name[name_max] = {0};
    90. while (1) {
    91. printf("请输入你要修改联系人的名字\n");
    92. scanf("%s", name);
    93. int k = find_name(Con, name);
    94. if ( k!= -1&&k>=0&&ksz) {
    95. printf("请重新输入修改的姓名\n");
    96. scanf("%s", Con->data[k].name);
    97. printf("请重新输入修改的的年龄\n");
    98. scanf("%d",&Con->data[k].age);
    99. printf("请重新输入修改的的性别\n");
    100. scanf("%s", Con->data[k].sex);
    101. printf("请重新输入修改的的号码\n");
    102. scanf("%s", Con->data[k].tele);
    103. printf("修改成功!\n");
    104. break;
    105. }
    106. else {
    107. printf("查无此人\n");
    108. break;
    109. }
    110. }
    111. }
    112. //删除联系人
    113. void Del_Peo(Contacts* Con) {
    114. assert(Con);
    115. if (Con->sz == 0) {
    116. printf("该通讯录还没有联系人\n");
    117. return;
    118. }
    119. printf("请输入你要删除联系人的姓名\n");
    120. char name1[name_max] = { 0 };
    121. scanf("%s", name1);
    122. int k = find_name(Con, name1);
    123. if (k != -1&&k>=0&&ksz) {
    124. for (int i = k; i < Con->sz - 1; i++) {
    125. Con->data[i] = Con->data[i + 1];
    126. }
    127. Con->sz--;
    128. printf("删除成功\n");
    129. }
    130. else {
    131. printf("查无此人\n");
    132. return;
    133. }
    134. }
    135. //展示联系人
    136. void Show_Peo(Contacts* Con) {
    137. assert(Con);
    138. if (Con->sz == 0) {
    139. printf("没有联系人\n");
    140. return;
    141. }
    142. printf("-------------------------------------------------\n");
    143. printf("|%-20s |%-5s |%-5s |%-12s| \n","姓名","年龄","性别","号码");
    144. printf("-------------------------------------------------\n");
    145. for (int i = 0; i < Con->sz; i++) {
    146. printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[i].name, Con->data[i].age, Con->data[i].sex, Con->data[i].tele);
    147. if (i != (Con->sz - 1)) {
    148. printf("-------------------------------------------------\n");
    149. }
    150. }
    151. printf("-------------------------------------------------\n");
    152. }
    153. //查询联系人
    154. void Sear_Peo(Contacts* Con) {
    155. assert(Con);
    156. char tager[name_max] = { 0 };
    157. if (Con->sz == 0) {
    158. printf("没有联系人\n");
    159. return;
    160. }
    161. printf("请输入你要查找的名字\n");
    162. scanf("%s", tager);
    163. int k = find_name(Con, tager);
    164. if (k != -1 && k >= 0 && k < Con->sz) {
    165. printf("-------------------------------------------------\n");
    166. printf("|%-20s |%-5s |%-5s |%-12s| \n", "姓名", "年龄", "性别", "号码");
    167. printf("|%-20s |%-5d |%-5s |%-12s|\n", Con->data[k].name, Con->data[k].age, Con->data[k].sex, Con->data[k].tele);
    168. printf("-------------------------------------------------\n");
    169. }
    170. else {
    171. printf("查无此人\n");
    172. return;
    173. }
    174. }
    175. //排序
    176. void Sort_Peo(Contacts* Con) {
    177. assert(Con);
    178. qsort(Con->data, Con->sz, sizeof(struct PeoInfo), cmp);
    179. printf("排序成功\n");
    180. return;
    181. }
    182. //销毁通讯录
    183. void Destory_Contacts(Contacts* Con) {
    184. free(Con->data);
    185. Con->data = NULL;
    186. Con->cap = 0;
    187. Con->sz = 0;
    188. }
    189. //保存数据到文件中
    190. void SaveContact(Contacts* Con) {
    191. assert(Con);
    192. FILE* pf = fopen("Contact.txt", "wb");
    193. if (pf == NULL) {
    194. perror("SaveContact");
    195. return;
    196. }
    197. for (int i = 0; i < Con->sz; i++) {
    198. fwrite(Con->data + i, sizeof(PeoInfo), 1, pf);
    199. }
    200. fclose(pf);
    201. pf = NULL;
    202. }
    203. //加载文件中的数据到通讯录中
    204. void LoadContact(Contacts* Con) {
    205. assert(Con);
    206. FILE* pf = fopen("Contact.txt", "rb");
    207. if (pf == NULL) {
    208. perror("LoadContact");
    209. return;
    210. }
    211. PeoInfo temp = { 0 };
    212. while (fread(&temp, sizeof(PeoInfo), 1, pf)) {
    213. check_cap(Con);
    214. Con->data[Con->sz] = temp;
    215. Con->sz++;
    216. }
    217. fclose(pf);
    218. pf = NULL;
    219. }

    好了以上就是整个项目的源代码了,是不是很简单呢?感兴趣的可以自己去试试哦!

  • 相关阅读:
    Citrix XenDesktop云桌面单点登录XenApp虚拟应用小技巧
    如何在Sage X3 ERP中使用集装箱管理和物流跟踪
    基于java小组学习系统计算机毕业设计源码+系统+lw文档+mysql数据库+调试部署
    C++零基础教程(函数重载)
    [ChatGPT] 从 GPT-3.5 到 GPT-5 的进化之路 | ChatGPT和程序员 : 协作 or 取代
    P1182 数列分段 Section II
    1093 Count PAT‘s
    MySQL笔记(进阶篇)
    全排列——dfs(剪枝/回溯)
    磨金石教育插画技能干货分享|插画怎么配色才好看?
  • 原文地址:https://blog.csdn.net/qq_62987647/article/details/133466779