C进阶:通讯录(动态版本 + 文件操作)附源码(下)

简介: C进阶:通讯录(动态版本 + 文件操作)附源码(下)

剩下的步骤很简单了,话不多说直接上源码;

七.源码

contact.h

1. #pragma once
2. 
3. //所需头文件的包含
4. #include <stdio.h>
5. #include <string.h>
6. #include <stdlib.h>
7. 
8. //一些定义的表示大小的宏
9. #define MAX_NAME 20
10. #define MAX_SEX  10
11. #define MAX_TEL  20
12. #define MAX_ADDR 30
13. 
14. #define DEFAULT_SZ 3  //默认通讯录容量
15. #define INC_SZ     2  //每次增容的大小
16. 
17. 
18. //定义每个联系人的信息
19. typedef struct peoinfo
20. {
21.   char name[MAX_NAME]; //姓名
22.   int age;  //年龄
23.   char sex[MAX_SEX];  //性别
24.   char tel[MAX_TEL];  //电话
25.   char addr[MAX_ADDR];  //地址
26. }peoinfo;
27. 
28. 
29. //存储每个联系人
30. typedef struct contact
31. {
32.   peoinfo* data;  //定义指针变量,方便后续动态内存开辟,进行通讯录扩容操作
33.   int sz;     //通过下标访问数组
34.   int capacity;  // 记录通讯录容量
35. }contact;
36. 
37. typedef struct sort
38. {
39.   peoinfo* sort;
40. }sort;
41. 
42. //动态初始化通讯录
43. void Innitcontact(contact* pc);
44. 
45. //打印通讯录
46. void printcontact(contact* pc);
47. 
48. //是否增容
49. void inccapacity(contact* pc);
50. 
51. 
52. //读入文件中的联系人信息
53. void download(contact* pc);
54. 
55. //保存文件中的联系人信息
56. void savecontact(contact* pc);
57. 
58. //销毁通讯录
59. void destroycontact(contact* pc);
60. 
61. //添加联系人
62. void addcontact(contact* pc);
63. 
64. //删除联系人
65. void delcontact(contact* pc);
66. 
67. //查找联系人
68. void searchcontact(contact* pc);
69. 
70. //修改联系人
71. void modifycontact(contact* pc);
72. 
73. //排序通讯录
74. void sortcontact(contact* pc);
75.

contact.c

1. #define _CRT_SECURE_NO_WARNINGS
2. 
3. #include "contact.h"
4. 
5. //将文件中的联系人信息读入
6. void download(contact* pc)
7. {
8.  FILE* pf = fopen("D:\\C\\c-code\\CONTACT\\CONTACT\\contact.txt", "r");  //以只读的方式打开文件
9.  if (pf == NULL)  //判断文件是否打开成功
10.   {
11.     perror("fopen");
12.     return;
13.   }
14. 
15.   peoinfo tmp = { 0 };
16.   while (fread(&tmp, sizeof(peoinfo), 1, pf))
17.   {
18.     inccapacity(pc);  //增容函数
19.     pc->data[pc->sz] = tmp;  //将联系人信息写入 data 中
20.     pc->sz++;  //记录写入联系人的数量
21.   }
22.   fclose(pf);  //关闭文件
23.   pf = NULL;
24. }
25. 
26. //保存文件中的联系人信息
27. void savecontact(contact* pc)
28. {
29.   FILE* pf = fopen("D:\\C\\c-code\\CONTACT\\CONTACT\\contact.txt", "w");  //以只写的方式打开文件
30.   if (pf == NULL)  //判断文件是否打开成功
31.   {
32.     perror("savecontact");
33.     return;
34.   }
35.   int i = 0;
36.   for (i = 0; i < pc->sz; i++)   
37.   {
38.     fwrite(pc->data + i, sizeof(peoinfo), 1, pf);  //向文件中写入通讯录的数据
39.   }
40.   fclose(pf);  //数据写完后,关闭文件
41.   pf = NULL;
42. }
43. 
44. //销毁通讯录
45. void destroycontact(contact* pc)
46. {
47.   pc->sz = 0;
48.   pc->capacity = DEFAULT_SZ;  //容量回复默认值
49.   free(pc->data);  //释放之前开辟的内存
50.   pc->data = NULL;  //指针置空,防止野指针的出现
51. }
52. 
53. //动态初始化联系人
54. void Innitcontact(contact* pc)
55. {
56.   pc->data = (peoinfo*)calloc(DEFAULT_SZ, sizeof(peoinfo));  //动态内存开辟,实现通讯录的动态
57.   if (pc->data == NULL)  //判断内存开辟是否成功
58.   {
59.     perror("Innitcontact");
60.     return;
61.   }
62.   pc->sz = 0;  //初始化通讯录实时容量,也可用作下标
63.   pc->capacity = DEFAULT_SZ;  //初始化容量
64.   download(pc);  //加载文件中联系人的信息
65. }
66. 
67. 
68. //打印通讯录
69. void printcontact(contact* pc)
70. {
71.   int i = 0;
72.   printf("%-20s\t%-5s\t%-10s\t%-20s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");  //打印的格式可以根据个人喜好来
73.   for (i = 0; i < pc->sz; i++)
74.   {
75.     printf("%-20s\t%-5d\t%-10s\t%-20s\t%-30s\n", pc->data[i].name,
76.                            pc->data[i].age,
77.                            pc->data[i].sex,
78.                            pc->data[i].tel,
79.                            pc->data[i].addr);
80.   }
81. }
82. 
83. //是否增容
84. void inccapacity(contact* pc)
85. {
86.   if (pc->sz == pc->capacity)
87.   {
88.     printf("通讯录已满,开始增容\n");
89.       peoinfo* ptr = (peoinfo*)realloc(pc->data,(DEFAULT_SZ+INC_SZ)*sizeof(peoinfo));  //利用 realloc 进行内存的再次动态开辟,实现通讯录的增容
90. 
91.     if(ptr == NULL)  //判断内存是否开辟成功
92.     {
93.       printf("增容失败\n");
94.       perror("inccapacity");
95.       return;
96.     }
97.     else
98.     {
99.       pc->data = ptr;   //将扩容后的通讯录首地址赋给原来的通讯录
100.      pc->capacity += INC_SZ;  //容量增加
101.      printf("增容成功\n");
102.    }
103.  }
104. }
105. 
106. //查找联系人
107. int find(char tmp[], contact* pc)
108. {
109.  int i = 0;
110.  for (i = 0; i < pc->sz; i++)
111.  {
112.    if (strcmp(tmp, pc->data[i].name) == 0)  //因为姓名是字符串,所以利用字符串比较函数
113.    {
114.      return i;  //查找成功返回其下标
115.    }
116.  }
117.  return -1;  //失败则返回-1
118. }
119. 
120. //添加联系人
121. void addcontact(contact* pc)
122. {
123.  int input = 0;
124.  do
125.  {
126. 
127.    printf("按1继续,按0返回:>");  //利用 do ... while 结构实现联系人的多次添加
128.    scanf("%d", &input);
129. 
130.    switch (input)
131.    {
132.    case 1:
133.      inccapacity(pc);  //判断容量是否已满,若已满,则进行增容
134.      printf("开始添加\n");  //联系人各种信息的录入
135.      printf("请输入姓名:>");
136.      scanf("%s", pc->data[pc->sz].name);
137.      printf("请输入年龄:>");
138.      scanf("%d", &(pc->data[pc->sz].age));
139.      printf("请输入性别:>");
140.      scanf("%s", pc->data[pc->sz].sex);
141.      printf("请输入电话:>");
142.      scanf("%s", pc->data[pc->sz].tel);
143.      printf("请输入地址:>");
144.      scanf("%s", pc->data[pc->sz].addr);
145.      pc->sz++;  //添加成功后,通讯录实时容量增加1
146.      printf("添加成功\n");
147.      break;
148.    case 0:
149.      printf("返回\n");
150.      return;
151.      break;
152.    default:
153.      printf("选择错误,重新选择\n");
154.      break;
155.    }
156.  } while (input);
157. }
158. 
159. //删除联系人
160. void delcontact(contact* pc)
161. {
162.  char tmp[MAX_NAME];  
163.  int pos = 0, i = 0;
164.  if (pc->sz == 0)  //判断通讯录有无数据
165.  {
166.    printf("通讯录为空,无法删除\n");
167.    return;
168.  }
169.  while (1)
170.  {
171.  again:
172.    printf("请输入要删除的人的姓名:>");
173.    scanf("%s", tmp);
174.    pos = find(tmp, pc);  //查找要删除人的下标
175.    if (pos == -1)
176.    {
177.      printf("要删除的人不存在,重新输入\n");
178.      goto again;
179.    }
180.    else
181.      break;
182.  }
183.  printf("开始删除\n");
184.  for (i = pos; i < pc->sz - 1; i++)  //从返回的下标 pos 开始 ,之后的每个元素向前移动一位
185.  {
186.    pc->data[i] = pc->data[i + 1];
187.  }
188.  pc->sz--;  //删除成功即通讯录的实时容量减去1
189.  printf("删除成功\n");
190. }
191. 
192. //查找联系人
193. void searchcontact(contact* pc)
194. {
195.  char name[MAX_NAME];
196.  int pos = 0;
197.  if (pc->sz == 0)    //判断通讯录中是否有数据
198.  {
199.    printf("通讯录为空,无法查询\n");
200.    return;
201.  }
202.  while (1)
203.  {
204.    again:
205.    printf("请输入要查找人的姓名:>");
206.    scanf("%s", name);
207.    pos = find(name, pc);  //调用 fing 函数,并返回其下标
208.    if (pos == -1)
209.    {
210.      printf("查无此人,重新查询\n");  //查询失败则继续
211.      goto again;
212.    }
213.    else
214.      break;
215.  }
216.  printf("查询成功\n");
217.  printf("%-20s\t%-5s\t%-10s\t%-20s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");   //打印该联系人的信息
218.  printf("%-20s\t%-5d\t%-10s\t%-20s\t%-30s\n", pc->data[pos].name,
219.                         pc->data[pos].age,
220.                         pc->data[pos].sex,
221.                         pc->data[pos].tel,
222.                         pc->data[pos].addr);
223. 
224. }
225. 
226. //修改联系人
227. void modifycontact(contact* pc)
228. {
229.  if (pc->sz == 0)  //判断通讯录是否有数据
230.  {
231.    printf("通讯录为空,无法修改\n");
232.    return;
233.  }
234.  char name[MAX_NAME];
235.  int pos = 0;
236.  while (1)
237.  {
238.    again:
239.    printf("请输入要修改的联系人的姓名:>");
240.    scanf("%s", name);
241.    pos = find(name, pc);  //返回要修改的联系人的下标
242.    if (pos == -1)
243.    {
244.      printf("要修改的联系人不存在,重新输入\n");
245.      goto again;
246.    }
247.    else
248.      break;
249.  }
250.  printf("开始修改\n");  //修改联系人信息
251.  printf("请输入姓名:>");
252.  scanf("%s", pc->data[pos].name);
253.  printf("请输入年龄:>");
254.  scanf("%d", &(pc->data[pos].age));
255.  printf("请输入性别:>");
256.  scanf("%s", pc->data[pos].sex);
257.  printf("请输入电话:>");
258.  scanf("%s", pc->data[pos].tel);
259.  printf("请输入地址:>");
260.  scanf("%s", pc->data[pos].addr);
261.  printf("修改成功\n");
262. }
263. 
264. 
265. //排序通讯录
266. void sortcontact(contact* pc)
267. {
268.  if (pc->sz < 2)
269.  {
270.    printf("通讯录数据不足,无法排序\n");  //判断是否支持排序
271.    return;
272.  }
273.  int i = 0, j = 0;
274.  sort S;  //变量的创建
275.  S.sort= (peoinfo*)calloc(pc->capacity, sizeof(peoinfo));  //sort 的初始化
276.  if (S.sort == NULL) //判断动态内存是否开辟成功
277.  {
278.    perror("sortcontact");
279.    return;
280.  }
281.  printf("开始排序\n");
282.  //qsort(pc, pc->sz, sizeof(peoinfo), cmp);
283.  for (i = 0; i < pc->sz - 1; i++)   //排序算法
284.  {
285.    for (j = i + 1; j < pc->sz; j++)
286.    {
287.      if (strcmp(pc->data[i].name, pc->data[j].name) > 0)
288.      {
289.        S.sort[i] = pc->data[i];  //交换元素
290.        pc->data[i] = pc->data[j];
291.        pc->data[j] = S.sort[i];
292.      }
293.    }
294.  }
295.  printf("排序成功\n");
296.  free(S.sort);  //排序成功后释放所开辟的内存
297.  S.sort = NULL;  //将指针置空,防止使用野指针
298. }

test.c

1. #define _CRT_SECURE_NO_WARNINGS
2. 
3. //头文件的包含
4. #include "contact.h"
5. 
6. 
7. //菜单
8. void menu()
9. {
10.   printf("*****************************************************************\n");
11.   printf("**********          1.add                 2.del        **********\n");
12.   printf("**********          3.search              4.modify     **********\n");
13.   printf("**********          5.see                 6.sort       **********\n");
14.   printf("**********                    0.exit                   **********\n");
15.   printf("*****************************************************************\n");
16. 
17. 
18. }
19. //利用枚举变量使代码表达的意思更清晰
20. enum option
21. {
22.   EXIT, //默认从0开始
23.   ADD,  //1
24.   DEL,  //2
25.   SEARCH,  //3
26.   MODIFY,  //4
27.   SEE,  //5
28.   SORT  //6
29. };
30. 
31. int main()
32. {
33.   int input = 0;
34.   contact con;   //通讯录变量创建
35.   //初始化联系人数组,包含从文件中读取联系人信息
36.   Innitcontact(&con);
37.   do
38.   {
39.     menu();
40.     printf("请选择:>");
41.     scanf("%d", &input);
42.     switch (input)
43.     {
44.     case ADD:
45.       addcontact(&con);  //添加
46.       break;
47.     case DEL:
48.       delcontact(&con);  //删除
49.       break;
50.     case SEARCH:
51.       searchcontact(&con);  //查找
52.       break;
53.     case MODIFY:
54.       modifycontact(&con);  //修改
55.       break;
56.     case SEE:
57.       printcontact(&con);  //打印通讯录
58.       break;
59.     case SORT:
60.       sortcontact(&con);  //排序
61.       break;
62.     case EXIT:
63.       savecontact(&con);  //保存通讯录,将联系人信息写入文件中
64.       destroycontact(&con);  //销毁通讯录
65.       printf("退出通讯录\n");
66.       break;
67.     default:
68.       printf("选择错误,重新选择\n");
69.       break;
70.     }
71.   } while (input);
72.   return 0;
73. }
目录
打赏
0
0
0
0
2
分享
相关文章
【c语言】通讯录(动态版+文件+背景音乐)含源码
【c语言】通讯录(动态版+文件+背景音乐)含源码
82 0
【C进阶】通讯录的实现(静态+动态)(上)
【C进阶】通讯录的实现(静态+动态)(上)
阅读小程序|基于微信阅读网站小程序的系统设计与实现(源码+数据库+文档)
阅读小程序|基于微信阅读网站小程序的系统设计与实现(源码+数据库+文档)
113 0
C进阶:通讯录(动态版本 + 文件操作)附源码(上)
C进阶:通讯录(动态版本 + 文件操作)附源码
49 0
【C语言实战项目】通讯录(动态增容版)
【C语言实战项目】通讯录(动态增容版)
47 0
【C进阶】通讯录的实现(静态+动态)(中)
【C进阶】通讯录的实现(静态+动态)(中)
【C进阶】通讯录的实现(静态+动态)(下)
【C进阶】通讯录的实现(静态+动态)(下)
【进阶C语言】动态版通讯录的实现(详细讲解+全部码源)
【进阶C语言】动态版通讯录的实现(详细讲解+全部码源)
【进阶C语言】动态版通讯录的实现(详细讲解+全部码源)