用结构体实现通讯录(动态实现)

简介: 🌸通讯录的需求🌸通讯录的功能🐰 通讯录的原码 🌸主函数🌸头文件🌸函数实现文件

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🌸通讯录的需求

🌸通讯录的功能

🐰 通讯录的原码

🌸主函数

🌸头文件

🌸函数实现文件


🌸通讯录的需求

1.人员的姓名

2.人员的年龄

3.人员的性别

4.人员的电话号码

5.人员的地址

实现方法:通讯录初始设置data_max(我这里设置3)个人的空间,开辟data_max个人的空间,动态创建(使用malloc)data_max个人的空间。我们设置两个结构体,一个保存通讯录的需求,一个保存结构体结构体动态创建的空间,通讯录的人数和通讯录最大容量。

🌸通讯录的功能

相较于静态的通讯录,我们改变了初始化通讯录,增加联系人的功能,添加了判断通讯录空间是否足够的函数,通讯录清空的功能。所以我只大家介绍改变的和新增的功能及函数

初始化通讯录:

1. //动态版本的初始化
2. void InitContact(Contact* pc)
3. {
4.     pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
5.     if(pc->data==NULL)
6.     {
7.         printf("开辟空间失败:%s\n",strerror(errno));
8.         return ;
9.     }
10.     pc->sz=0;
11.     pc->capacity=data_max;//容量最大空间当然也是data_max
12. }

初始化时,最开始给通讯录动态开辟data_max个空间,如果开辟空间失败时,打印出开辟空间失败的原因,开辟成功,将联系人的个数置为0,通讯录的空间置为data_max。

判断通讯录空间是否足够:

1. int CheckCapacity(Contact* pc)
2. {
3. if(pc->sz==pc->capacity)
4.     {
5.         PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
6. if(ptr==NULL)
7.         {
8. printf("增容失败:%s\n",strerror(errno));
9. return 0;
10.         }
11. else
12.         {
13.             pc->data=ptr;
14.             pc->capacity=pc->capacity*2;
15. printf("增容成功,容量为%d\n",pc->capacity);
16. return 1;
17.         }
18.     }
19. return 1;
20. }

如果联系人的个数等于通讯录的最大空间,则需要给通讯录扩容,这里采用的是扩容为原来空间两倍的方式扩容。如果扩容失败,打印扩容失败的原因。如果扩容成功,将扩容空间的首地址保存下来,将通讯录的最大容量更新为原来的两倍。还有,如果扩容成功或则不需要就返回1,扩容失败就返回0。

增加联系人:

1. void AddContact(Contact* pc)
2. {
3. if(CheckCapacity(pc)==0)
4.     {
5. printf("扩容失败\n");
6. return;
7.     }
8. else
9.     {
10. printf("请输入名字\n");
11. scanf("%s",pc->data[pc->sz].name);
12. printf("请输入年龄\n");
13. scanf("%d",&(pc->data[pc->sz].age));
14. printf("请输入性别\n");
15. scanf("%s",pc->data[pc->sz].sex);
16. printf("请输入电话号码\n");
17. scanf("%s",pc->data[pc->sz].tele);
18. printf("请输入地址\n");
19. scanf("%s",pc->data[pc->sz].addr);
20.         pc->sz++;
21. printf("添加成功\n");
22.     }
23. }

如果通过判断通讯录空间是否足够的函数得到返回值为1,我们就可以添加联系人的信息,如果返回值为0,就结束该进程。

通讯录清空:

1. void DestroyContact(Contact* pc)
2. {
3. free(pc->data);
4.     pc->data=NULL;
5.     pc->sz=0;
6.     pc->capacity=0;
7. printf("清空通讯录...\n");
8. }

因为我们是动态开辟空间去创建的通讯录,所以需要手动去释放这些动态开辟的空间,因为系统在程序结束之前,是不会自动释放在堆使用的空间。这样做的目的也刚好满足清空通讯录的要求。

🐰 通讯录的原码

🌸主函数

1. #include"test.h"
2. void menu(void)
3. {
4. printf("===========================\n");
5. printf("        1.添加,2.删除       \n");
6. printf("        3.查找,4.改动       \n");
7. printf("        5.展示,6.排序       \n");
8. printf("        7.清空,0.退出             \n");
9. printf("===========================\n");
10. }
11. enum Option
12. {
13.     EXIT,
14.     ADD,
15.     DEL,
16.     SEARCH,
17.     MODIFY,
18.     SHOW,
19.     SORT,
20.     DESTROY,
21. };
22. int main()
23. {
24.     Contact con;
25. InitContact(&con);
26. int input=0;
27. int op=0;
28. do
29.     {
30. menu();
31. printf("请选择\n");
32. scanf("%d",&input);
33. switch(input)
34.         {
35. case ADD:
36. AddContact(&con);
37. break;
38. case DEL:
39. DelContact(&con);
40. break;
41. case SEARCH:
42. SearchContact(&con);
43. break;
44. case MODIFY:
45. ModifyContact(&con);
46. break;
47. case SHOW:
48. ShowContact(&con);
49. break;
50. case SORT:
51. printf("请选择排序方法\n");
52. printf("=========================\n");
53. printf("1.按名字排序     2.按年龄排序\n");
54. printf("=========================\n");
55. scanf("%d",&op);
56. SortContact(&con,op);
57. case DESTROY:
58. DestroyContact(&con);
59. break;
60. case EXIT:
61. DestroyContact(&con);
62. printf("退出通讯录\n");
63. break;
64. default:
65. printf("输入错误\n");
66. break;
67.         }
68.     }while(input);
69. }

🌸头文件

1. #ifndef test_h
2. #define test_h
3. #include <stdio.h>
4. #endif /* test_h */
5. 
6. #include<string.h>
7. #include<stdlib.h>
8. #include<errno.h>
9. 
10. #define MAX 100
11. #define MAX_NAME 20
12. #define MAX_SEX 5
13. #define MAX_TELE 12
14. #define MAX_ADDR 30
15. 
16. 
17. #define data_max 3
18. typedef struct PeoInfo
19. {
20. char name[MAX_NAME];
21. int age;
22. char sex[MAX_SEX];
23. char tele[MAX_TELE];
24. char addr[MAX_ADDR];
25. }PeoInfo;
26. 
27. //typedef struct Contact
28. //{
29. //    PeoInfo data[MAX];//存放数据
30. //    int sz;//有效信息的个数
31. //}Contact;
32. 
33. 
34. 
35. //动态的版本
36. //1.默认能够存储3个人的信息
37. //2.不够扩容为原来空间的两倍
38. 
39. typedef struct Contact
40. {
41.     PeoInfo *data;//存放数据
42. int sz;//有效信息的个数
43. int capacity;//通讯录当前最大容量
44. }Contact;
45. 
46. 
47. 
48. 
49. //初始化
50. void InitContact(Contact* pc);
51. //增加指定联系人
52. void AddContact(Contact* pc);
53. //展示联系人的信息
54. void ShowContact(Contact* pc);
55. //删除指定人信息
56. void DelContact(Contact* pc);
57. //查找指定人的信息
58. void SearchContact(Contact* pc);
59. //改变指定人信息
60. void ModifyContact(Contact* pc);
61. //给通讯录的人信息排序
62. void SortContact(Contact* pc,int op);
63. //清空通讯录
64. void DestroyContact(Contact* pc);

🌸函数实现文件

1. #include "test.h"
2. //静态版本的初始化
3. //void InitContact(Contact* pc)
4. //{
5. //    pc->sz=0;
6. //    memset(pc->data,0,sizeof(pc->data));
7. //}
8. //动态版本的初始化
9. void InitContact(Contact* pc)
10. {
11.     pc->data=(PeoInfo*)malloc(sizeof(PeoInfo)*data_max);//最开始给通讯录开辟data_max个空间
12. if(pc->data==NULL)
13.     {
14. printf("开辟空间失败:%s\n",strerror(errno));
15. return ;
16.     }
17.     pc->sz=0;
18.     pc->capacity=data_max;//容量最大空间当然也是data_max
19. }
20. //静态增加人员的信息
21. //void AddContact(Contact* pc)
22. //{
23. //    if(pc->sz==MAX)
24. //    {
25. //        printf("通讯录已满,无法增加\n");
26. //    }
27. //    else
28. //    {
29. //        printf("请输入名字\n");
30. //        scanf("%s",pc->data[pc->sz].name);
31. //        printf("请输入年龄\n");
32. //        scanf("%d",&(pc->data[pc->sz].age));
33. //        printf("请输入性别\n");
34. //        scanf("%s",pc->data[pc->sz].sex);
35. //        printf("请输入电话号码\n");
36. //        scanf("%s",pc->data[pc->sz].tele);
37. //        printf("请输入地址\n");
38. //        scanf("%s",pc->data[pc->sz].addr);
39. //    }
40. //    pc->sz++;
41. //    printf("添加成功\n");
42. //}
43. 
44. //检查是否需要扩容
45. int CheckCapacity(Contact* pc)
46. {
47. if(pc->sz==pc->capacity)
48.     {
49.         PeoInfo* ptr=(PeoInfo*)realloc(pc->data,sizeof(pc->capacity)*2);
50. if(ptr==NULL)
51.         {
52. printf("增容失败:%s\n",strerror(errno));
53. return 0;
54.         }
55. else
56.         {
57.             pc->data=ptr;
58.             pc->capacity=pc->capacity*2;
59. printf("增容成功,容量为%d\n",pc->capacity);
60. return 1;
61.         }
62.     }
63. return 1;
64. }
65. //动态增加人员信息
66. void AddContact(Contact* pc)
67. {
68. if(CheckCapacity(pc)==0)
69.     {
70. printf("扩容失败\n");
71. return;
72.     }
73. else
74.     {
75. printf("请输入名字\n");
76. scanf("%s",pc->data[pc->sz].name);
77. printf("请输入年龄\n");
78. scanf("%d",&(pc->data[pc->sz].age));
79. printf("请输入性别\n");
80. scanf("%s",pc->data[pc->sz].sex);
81. printf("请输入电话号码\n");
82. scanf("%s",pc->data[pc->sz].tele);
83. printf("请输入地址\n");
84. scanf("%s",pc->data[pc->sz].addr);
85.         pc->sz++;
86. printf("添加成功\n");
87.     }
88. }
89. 
90. void ShowContact(Contact* pc)
91. {
92. printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
93. for(int i=0;i<pc->sz;i++)
94.     {
95. printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].tele,pc->data[i].addr);
96.     }
97. }
98. int Find_name(Contact* pc,char name[])
99. {
100. int i;
101. int pos=-1;
102. for( i=0;i<pc->sz;i++)
103.     {
104. if(strcmp(name,pc->data[i].name)==0)
105.         {
106.             pos=i;
107. break;
108.         }
109.     }
110. return pos;
111. }
112. void DelContact(Contact* pc)
113. {
114. if(pc->sz==0)
115.     {
116. printf("通讯录为空,无法删除\n");
117.     }
118. //删除
119. //1.找到删除人的位置
120. char name[MAX_NAME];
121. int pos=-1;
122. int i;
123. printf("输入删除人的名字;>\n");
124. scanf("%s",name);
125.     pos=Find_name(pc,name);
126. if(pos==-1)
127.     {
128. printf("要删的人不存在\n");
129.     }
130. else{
131. for(i=pos;i<pc->sz-1;i++)
132.         {
133.             pc->data[i]=pc->data[i+1];
134.         }
135.         pc->sz--;
136. printf("删除成功\n");
137.     }
138. }
139. void SearchContact(Contact* pc)
140. {
141. char name[MAX_NAME];
142. printf("输入查找人的名字;>\n");
143. scanf("%s",name);
144. int pos=-1;
145.     pos=Find_name(pc, name);
146. if(pos==-1)
147.     {
148. printf("查找的人不存在\n");
149.     }
150. else
151.     {
152. printf("%-10s %-4s %-5s %-12s %-30s\n","性别","年龄","性别","电话号码","地址");
153. printf("%-10s %-4d %-5s %-12s %-30s\n",pc->data[pos].name,pc->data[pos].age,pc->data[pos].sex,pc->data[pos].tele,pc->data[pos].addr);
154.     }
155. }
156. void ModifyContact(Contact* pc)
157. {
158. char name[MAX_NAME];
159. printf("输入修改人的名字;>\n");
160. scanf("%s",name);
161. int pos=-1;
162.     pos=Find_name(pc, name);
163. if(pos==-1)
164.     {
165. printf("修改人信息不存在\n");
166.     }
167. else
168.     {
169. printf("请输入名字\n");
170. scanf("%s",pc->data[pos].name);
171. printf("请输入年龄\n");
172. scanf("%d",&(pc->data[pos].age));
173. printf("请输入性别\n");
174. scanf("%s",pc->data[pos].sex);
175. printf("请输入电话号码\n");
176. scanf("%s",pc->data[pos].tele);
177. printf("请输入地址\n");
178. scanf("%s",pc->data[pos].addr);
179. printf("修改成功\n");
180.     }
181. }
182. int cmp_by_name(const void* e1,const void* e2)
183. {
184. return strcmp(((PeoInfo*)e1)->name,((PeoInfo*)e2)->name);
185. }
186. int cmp_by_gae(const void* e1,const void* e2)
187. {
188. return ((PeoInfo*)e1)->age-((PeoInfo*)e2)->age;
189. }
190. void SortContact(Contact* pc,int op)
191. {
192. if(op==1)
193.     {
194. qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_name);
195. printf("排序成功\n");
196.     }
197. if(op==2)
198.     {
199. qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_gae);
200. printf("排序成功\n");
201.     }
202. }
203. void DestroyContact(Contact* pc)
204. {
205. free(pc->data);
206.     pc->data=NULL;
207.     pc->sz=0;
208.     pc->capacity=0;
209. printf("清空通讯录...\n");
210. }

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸

相关文章
【动态通讯录】
【动态通讯录】
48 0
|
7月前
|
存储 编译器 C语言
通讯录详解(静态版,动态版,文件版)
通讯录详解(静态版,动态版,文件版)
112 0
|
存储
【静态通讯录】
【静态通讯录】
42 0
|
程序员 编译器 C语言
C语言---认识动态内存管理并实现一个动态通讯录:静态通讯录别来沾边
C语言学习——动态内存管理(上)+优化版通讯录+笔试题
|
存储
通讯录(静态版)
通讯录(静态版)
110 0
|
C语言
C/【静态通讯录】
C/【静态通讯录】
静态通讯录
C语言学习——教你学会静态通讯录的实现(保姆级教程哦~)
静态版通讯录
大家好,今天我为大家带来的是静态版本的通讯录(后期也会更新更优版本的通讯录,记得关注,防止找不到了哦)。 我将通讯录分别放在三个不同的文件中,分别是test.c(用来实现代码的额整体逻辑),Contact.h(用来存放头文件和函数声明),Contact.c(函数实现的主体)。那么就随我来看看怎样实现静态版本的通讯录吧。
动态版通讯录
来了朋友们,今天给大家分享的是动态版本的通讯录。这个动态版本的通讯录较静态版本的通讯录的好处是,动态版本的通讯录对空间的浪费较少,并且可以随时增加空间,使用更加灵活。其实基本逻辑是跟静态版本的通讯录是一样的。