• 动态通讯录及程序保存在文件中


    目录

    一、结构体改造及增容函数

    1.结构体部分

    2.初始化函数及增容函数

    二、信息添加及销毁和排序

    1.信息添加函数(Add)

    2.销毁函数(Destroy)

    3.排序部分(qsort)

    三、通讯录信息保存

    1.保存在文件中(输出操作)

    2.加载通讯录(输入操作)

    四、整理通讯录

    1.在菜单按0后退出程序

    2.其他方式退出程序

    3.打开程序就加载通讯录

    4.完整通讯录代码


    前言:这一次是在之前静态的通讯录基础上进行改造;变成动态通讯录,当空间不够时,可以完成自动增容,并且将通讯录中的信息保存在文件中,退出或关闭程序就不会再丢失数据。

    先看静态通讯录的代码:

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define NAME_MAX 20
    7. #define SEX_MAX 6
    8. #define TELE_MAX 20
    9. #define ADDR_MAX 20
    10. #define MAX 100
    11. typedef struct PeoInfo
    12. {
    13. char name[NAME_MAX];//姓名
    14. char sex[SEX_MAX];//性别
    15. int age;//年龄
    16. char tele[TELE_MAX];//电话
    17. char addr[ADDR_MAX];//地址
    18. }PeoInfo;
    19. typedef struct contact
    20. {
    21. PeoInfo data[MAX];//通讯录
    22. int sz;//记录通讯录的个数
    23. }contact;
    24. //函数的声明
    25. //初始化
    26. void InitContact(contact* pc);
    27. //添加用户信息
    28. void AddContact(contact* pc);
    29. //打印通讯录
    30. void ShowContact(contact* pc);
    31. //删除联系人
    32. void DelContact(contact* pc);
    33. //查找某个联系人
    34. void SearchContact(contact* pc);
    35. //修改联系人
    36. void ModifyContact(contact* pc);
    37. //联系人排序
    38. void SortContact(contact* pc);
    39. //函数功能的实现
    40. void InitContact(contact* pc)
    41. {
    42. assert(pc);
    43. memset(pc->data,0,sizeof(pc->data));
    44. pc->sz = 0;
    45. }
    46. void ShowContact(contact* pc)
    47. {
    48. assert(pc);
    49. if (pc->sz == 0)
    50. {
    51. printf("通讯录为空\n");
    52. return;
    53. }
    54. printf("%-10s %-5s %-10s %-15s %-10s\n","名字","性别","年龄","电话","住址");
    55. int i = 0;
    56. for (i=0;isz;i++)
    57. {
    58. printf("%-10s %-5s %-10d %-15s %-10s\n",
    59. pc->data[i].name, pc->data[i].sex, pc->data[i].age,
    60. pc->data[i].tele, pc->data[i].addr);
    61. }
    62. printf("\n");
    63. }
    64. void AddContact(contact* pc)
    65. {
    66. assert(pc);
    67. int adds;
    68. back:
    69. if (pc->sz == MAX)
    70. {
    71. printf("通讯录已满,存入信息失败\n");
    72. return;
    73. }
    74. printf("请输入姓名>:");
    75. scanf("%s", pc->data[pc->sz].name);
    76. printf("请输入性别>:");
    77. scanf("%s", pc->data[pc->sz].sex);
    78. printf("请输入年龄>:");
    79. scanf("%d", &(pc->data[pc->sz].age));
    80. printf("请输入电话>:");
    81. scanf("%s", pc->data[pc->sz].tele);
    82. printf("请输入住址>:");
    83. scanf("%s", pc->data[pc->sz].addr);
    84. pc->sz++;
    85. printf("信息添加成功\n");
    86. printf("是否继续添加联系人信息1/0:");
    87. scanf("%d",&adds);
    88. if (adds == 1)
    89. goto back;
    90. else
    91. {
    92. return;
    93. }
    94. }
    95. //查看某个联系人是否存在
    96. static int FindContact(contact* pc,char name[])
    97. {
    98. assert(pc);
    99. int i = 0;
    100. for (i=0;isz;i++)
    101. {
    102. if (strcmp(name, pc->data[i].name) == 0)
    103. return i;
    104. }
    105. return -1;
    106. }
    107. //删除联系人
    108. void DelContact(contact* pc)
    109. {
    110. assert(pc);
    111. if (pc->sz == 0)
    112. {
    113. printf("通讯录为空,删除失败\n");
    114. return;
    115. }
    116. printf("请输入你要删除的联系人:");
    117. char name[NAME_MAX];
    118. scanf("%s",name);
    119. int ret = FindContact(pc,name);
    120. if (ret == -1)
    121. {
    122. printf("联系人不存在,删除失败\n");
    123. return;
    124. }
    125. int i = 0;
    126. for (i=ret;isz-1;i++)
    127. {
    128. pc->data[i] = pc->data[i + 1];
    129. }
    130. pc->sz--;
    131. printf("删除联系人成功\n");
    132. }
    133. //查找联系人
    134. void SearchContact(contact* pc)
    135. {
    136. assert(pc);
    137. printf("请输入你要查找联系人的名字:");
    138. char name[NAME_MAX];
    139. scanf("%s", name);
    140. int ret = FindContact(pc, name);
    141. if (ret == -1)
    142. {
    143. printf("联系人不存在,查找失败\n");
    144. return;
    145. }
    146. printf("查找成功:\n");
    147. printf("%-10s %-5s %-10s %-15s %-10s\n", "名字", "性别", "年龄", "电话", "住址");
    148. printf("%-10s %-5s %-10d %-15s %-10s\n",
    149. pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
    150. pc->data[ret].tele, pc->data[ret].addr);
    151. }
    152. //修改联系人
    153. void ModifyContact(contact* pc)
    154. {
    155. assert(pc);
    156. printf("请输入你要查找联系人的名字:");
    157. char name[NAME_MAX];
    158. scanf("%s", name);
    159. int ret = FindContact(pc, name);
    160. if (ret == -1)
    161. {
    162. printf("联系人不存在,修改失败\n");
    163. return;
    164. }
    165. printf("联系人存在:");
    166. printf("%-10s %-5s %-10d %-15s %-10s\n",
    167. pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
    168. pc->data[ret].tele, pc->data[ret].addr);
    169. printf("请修改姓名>:");
    170. scanf("%s", pc->data[ret].name);
    171. printf("请修改性别>:");
    172. scanf("%s", pc->data[ret].sex);
    173. printf("请修改年龄>:");
    174. scanf("%d", &(pc->data[ret].age));
    175. printf("请修改电话>:");
    176. scanf("%s", pc->data[ret].tele);
    177. printf("请修改住址>:");
    178. scanf("%s", pc->data[ret].addr);
    179. printf("\n修改成功");
    180. }
    181. //分类菜单
    182. void menu2()
    183. {
    184. printf("*************************\n");
    185. printf("**** 1.名字 2.年龄 ****\n");
    186. printf("*************************\n");
    187. }
    188. //名字排序
    189. int qsort_cmp_name(const void* e1,const void* e2)
    190. {
    191. return strcmp((((contact*)e1)->data)->name, (((contact*)e2)->data)->name);
    192. }
    193. //年龄排序
    194. int qsort_cmp_age(const void* e1,const void* e2)
    195. {
    196. return (((contact*)e1)->data)->age - (((contact*)e2)->data)->age;
    197. }
    198. //联系人排序
    199. void SortContact(contact* pc)
    200. {
    201. int input2;
    202. menu2();
    203. printf("请选择排序方式:");
    204. scanf("%d",&input2);
    205. switch (input2)
    206. {
    207. case 1:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_name);
    208. case 2:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_age);
    209. defualt:printf("选择错误\n");
    210. break;
    211. }
    212. }
    213. //主函数及菜单
    214. void menu()
    215. {
    216. printf("********************************\n");
    217. printf("**** 1. add 2. del ****\n");
    218. printf("**** 3. search 4. modify ****\n");
    219. printf("**** 5. show 6. sort ****\n");
    220. printf("**** 0. exit ****\n");
    221. printf("********************************\n");
    222. }
    223. enum Option
    224. {
    225. EXIT,//退出
    226. ADD,//增加
    227. DEL,//删除联系人
    228. SEARCH,//查找联系人
    229. MODIFY,//修改指定联系人
    230. SHOW,//打印联系人
    231. SORT,//分类
    232. };
    233. int main()
    234. {
    235. contact con;
    236. InitContact(&con);
    237. int input;
    238. do
    239. {
    240. menu();
    241. printf("请输入你的选择>:");
    242. scanf("%d",&input);
    243. switch (input)
    244. {
    245. case ADD:AddContact(&con);
    246. break;
    247. case DEL:DelContact(&con);
    248. break;
    249. case SEARCH:SearchContact(&con);
    250. break;
    251. case MODIFY:ModifyContact(&con);
    252. break;
    253. case SHOW:ShowContact(&con);
    254. break;
    255. case SORT:SortContact(&con);
    256. break;
    257. case EXIT:printf("你已选择退出程序\n");
    258. break;
    259. default:printf("选择错误,请重新选择\n");
    260. break;
    261. }
    262. } while (input);
    263. return 0;
    264. }

    我们将对其进行改造。

    一、结构体改造及增容函数

    1.结构体部分

    1. typedef struct PeoInfo
    2. {
    3. char name[NAME_MAX];//姓名
    4. char sex[SEX_MAX];//性别
    5. int age;//年龄
    6. char tele[TELE_MAX];//电话
    7. char addr[ADDR_MAX];//地址
    8. }PeoInfo;
    9. typedef struct contact
    10. {
    11. PeoInfo* data;//通讯录指针
    12. int capacity;//通讯录最大容量
    13. int sz;//记录通讯录的个数
    14. }contact;

    (1)通讯录的内容不需要修改。

    (2)因为数组是不可能动态变化大小,所以改成指针,可以指向一块空间,就可以使用realloc进行增容。

    2.初始化函数及增容函数

    (1)初始化函数

    1. #define INCAPA 3//capacity初始容量
    2. //动态初始化版本
    3. void InitContact(contact* pc)
    4. {
    5. assert(pc);
    6. pc->sz = 0;
    7. pc->capacity = INCAPA;
    8. pc->data = calloc(pc->capacity, sizeof(PeoInfo));
    9. if (pc->data == NULL)
    10. {
    11. perror("InitContact->calloc");
    12. return 1;
    13. }
    14. }

    (1)sz刚开始是0,capacity开始的容量我们赋值INCAPA,也就是3

    (2)使用calloc将开辟好的一块空间赋值给data

    (2)增容函数 

    1. //增容函数
    2. void CheckCapacity(contact* pc)
    3. {
    4. if (pc->sz == pc->capacity)
    5. {
    6. PeoInfo* str = (PeoInfo*)realloc(pc->data, (pc->capacity + 5) * sizeof(PeoInfo));
    7. if (str != NULL)
    8. {
    9. pc->data = str;
    10. pc->capacity += 5;
    11. printf("增容成功\n");
    12. }
    13. else
    14. {
    15. perror("CheckCapacity->realloc");
    16. return;
    17. }
    18. }
    19. }

    (1)该函数用来扩容

    (2)sz==capacity说明通讯录已满需要扩容,每次增加5个空间

    二、信息添加及销毁和排序

    1.信息添加函数(Add)

    1. //动态版本
    2. void AddContact(contact* pc)
    3. {
    4. assert(pc);
    5. CheckCapacity(pc);//检查通讯录是否满
    6. int adds;
    7. back:
    8. printf("请输入姓名>:");
    9. scanf("%s", pc->data[pc->sz].name);
    10. printf("请输入性别>:");
    11. scanf("%s", pc->data[pc->sz].sex);
    12. printf("请输入年龄>:");
    13. scanf("%d", &(pc->data[pc->sz].age));
    14. printf("请输入电话>:");
    15. scanf("%s", pc->data[pc->sz].tele);
    16. printf("请输入住址>:");
    17. scanf("%s", pc->data[pc->sz].addr);
    18. pc->sz++;
    19. printf("信息添加成功\n");
    20. printf("是否继续添加联系人信息1/0:");
    21. scanf("%d", &adds);
    22. if (adds == 1)
    23. goto back;
    24. else
    25. {
    26. return;
    27. }
    28. }

    (1)在添加信息的时候,检查容量是否已满,满则扩容

    2.销毁函数(Destroy)

    1. //销毁通讯录
    2. void DestroyContact(contact* pc)
    3. {
    4. free(pc->data);
    5. pc->data = NULL;
    6. pc->sz = 0;
    7. pc->capacity = 0;
    8. }

    calloc和realloc开辟的内存为动态内存,程序结束需要及时释放

    3.排序部分(qsort)

    1. void menu2()
    2. {
    3. printf("*************************\n");
    4. printf("**** 1.名字 2.年龄 ****\n");
    5. printf("*************************\n");
    6. }
    7. //动态排序
    8. //名字排序
    9. int qsort_cmp_name(const void* e1, const void* e2)
    10. {
    11. return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
    12. }
    13. //年龄排序
    14. int qsort_cmp_age(const void* e1, const void* e2)
    15. {
    16. return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
    17. }
    18. //联系人排序
    19. void SortContact(contact* pc)
    20. {
    21. int input2;
    22. menu2();
    23. printf("请选择排序方式:");
    24. scanf("%d", &input2);
    25. switch (input2)
    26. {
    27. case 1:qsort(pc->data, pc->sz, sizeof(PeoInfo), qsort_cmp_name); break;
    28. case 2:qsort(pc->data, pc->sz, sizeof(PeoInfo), qsort_cmp_age); break;
    29. defualt:printf("选择错误\n");
    30. break;
    31. }
    32. }

    这个排序代码同样适用于静态通讯录。

    三、通讯录信息保存

    1.保存在文件中(输出操作)

    为了将通讯录中的信息保存下来,所以我们需要将程序写入文件中,从而可以达到保存数据的目的,下面是文件保存的代码:

    1. //通讯录信息保存
    2. void SaveContact(contact* pc)
    3. {
    4. assert(pc);
    5. //打开文件
    6. FILE* pf = fopen("contact.txt", "wb");
    7. if (pf == NULL)
    8. {
    9. perror("SaveContact");
    10. return 1;
    11. }
    12. //写文件
    13. int i = 0;
    14. for (i = 0; i < pc->sz; i++)
    15. {
    16. fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);//fwrite写文件更方便
    17. }
    18. //关闭文件
    19. fclose(pf);
    20. pf = NULL;
    21. }

    (1)我们利用fwrite函数以二进制的形式将数据写入contact.txt的文本中、

    (2)每一次写一个人的信息

    2.加载通讯录(输入操作)

    单单将数据保存到文件中还不行,下次再将程序运行起来,还是一个空的通讯录,因为上次的数据在文件中,所以我们需要将文件中的数据输入程序中,这就是读文件的操作:

    1. //加载通讯录
    2. void LoadContact(contact* pc)
    3. {
    4. assert(pc);
    5. FILE* pf = fopen("contact.txt", "rb");
    6. if (pf == NULL)
    7. {
    8. perror("LoadContact");
    9. return 1;
    10. }
    11. PeoInfo tmp = { 0 };//用来存放fread读写的信息
    12. while (fread(&tmp, sizeof(PeoInfo), 1, pf))
    13. {
    14. //检查容量
    15. CheckCapacity(pc);
    16. pc->data[pc->sz] = tmp;
    17. pc->sz++;
    18. }
    19. fclose(pf);
    20. pf = NULL;
    21. }

    (1)我们将文件中的通讯录信息加载出来,需要考虑通讯录的空间是否足够,否则需要增容

    (2)然后同理将通讯录的信息一个个输出出来

    四、整理通讯录

    上述已经写好了文件保存的程序,接下来就需要调用,当程序退出时就可以及时保存到文件中。

    退出的情况有很多种:

    1.在菜单按0后退出程序

    下面的代码是正常退出程序时的操作:

    1. case EXIT:SaveContact(&con);//将通讯录保存于文件中
    2. DestroyContact(&con);
    3. printf("你已选择退出程序\n");
    4. break;

    2.其他方式退出程序

    暴力退出,如:直接叉掉程序、直接关掉软件(VS),这些也需要单独考虑

    (1)增加信息后暴力退出

    那我们就在增加信息函数后面加上一个文件保存函数,每次调用增容函数后就及时保存

    1. case ADD:AddContact(&con);
    2. SaveContact(&con);
    3. break;

    (2)删除信息后暴力退出

    删除信息后不及时保存,然后暴力退出依旧达不到删除信息的目的,所以也需要在调用删除函数后面补上文件保存函数。

    1. case DEL:DelContact(&con);
    2. SaveContact(&con);
    3. break;

    (3)排序后暴力退出

    排序同理,排完序就及时保存。

    1. case SORT:SortContact(&con);
    2. SaveContact(&con);
    3. break;

    (4)修改信息后暴力退出

    修改同理,修改后及时保存信息 

    1. case MODIFY:ModifyContact(&con);
    2. SaveContact(&con);
    3. break;

    3.打开程序就加载通讯录

    当每次把程序运行起来之后,就希望已经将文件中的信息加载到程序中了,所以需要在初始化函数处进行改造,加上加载文件的函数接口即可

    1. void InitContact(contact* pc)
    2. {
    3. assert(pc);
    4. pc->sz = 0;
    5. pc->capacity = INCAPA;
    6. pc->data = calloc(pc->capacity, sizeof(PeoInfo));
    7. if (pc->data == NULL)
    8. {
    9. perror("InitContact->calloc");
    10. return 1;
    11. }
    12. //每次初始化前可以先打开之前的通讯录
    13. LoadContact(pc);
    14. }

    4.完整通讯录代码

    1. #define _CRT_SECURE_NO_WARNINGS 1
    2. #include
    3. #include
    4. #include
    5. #include
    6. #define NAME_MAX 20
    7. #define SEX_MAX 6
    8. #define TELE_MAX 20
    9. #define ADDR_MAX 30
    10. #define MAX 100
    11. #define INCAPA 3//capacity初始容量
    12. typedef struct PeoInfo
    13. {
    14. char name[NAME_MAX];//姓名
    15. char sex[SEX_MAX];//性别
    16. int age;//年龄
    17. char tele[TELE_MAX];//电话
    18. char addr[ADDR_MAX];//地址
    19. }PeoInfo;
    20. //静态的通讯录
    21. //typedef struct contact
    22. //{
    23. // PeoInfo data[MAX];//通讯录
    24. // int sz;//记录通讯录的个数
    25. //}contact;
    26. //动态版本
    27. typedef struct contact
    28. {
    29. PeoInfo* data;//通讯录
    30. int capacity;//通讯录最大容量
    31. int sz;//记录通讯录的个数
    32. }contact;
    33. //初始化
    34. void InitContact(contact* pc);
    35. //添加用户信息
    36. void AddContact(contact* pc);
    37. //打印通讯录
    38. void ShowContact(contact* pc);
    39. //删除联系人
    40. void DelContact(contact* pc);
    41. //查找某个联系人
    42. void SearchContact(contact* pc);
    43. //修改联系人
    44. void ModifyContact(contact* pc);
    45. //联系人分类
    46. void SortContact(contact* pc);
    47. //增容函数
    48. void CheckCapacity(contact* pc);
    49. //销毁通讯录
    50. void DestroyContact(contact* pc);
    51. //文件保存函数
    52. void SaveContact(contact* pc);
    53. //加载通讯录
    54. void LoadContact(contact* pc);
    55. #define _CRT_SECURE_NO_WARNINGS 1
    56. //静态初始化
    57. //void InitContact(contact* pc)
    58. //{
    59. // assert(pc);
    60. // memset(pc->data, 0, sizeof(pc->data));
    61. // pc->sz = 0;
    62. //}
    63. //动态初始化版本
    64. void InitContact(contact* pc)
    65. {
    66. assert(pc);
    67. pc->sz = 0;
    68. pc->capacity = INCAPA;
    69. pc->data = calloc(pc->capacity, sizeof(PeoInfo));
    70. if (pc->data == NULL)
    71. {
    72. perror("InitContact->calloc");
    73. return 1;
    74. }
    75. //每次初始化前可以先打开之前的通讯录
    76. LoadContact(pc);
    77. }
    78. //加载通讯录
    79. void LoadContact(contact* pc)
    80. {
    81. assert(pc);
    82. FILE* pf = fopen("contact.txt", "rb");
    83. if (pf == NULL)
    84. {
    85. perror("LoadContact");
    86. return 1;
    87. }
    88. PeoInfo tmp = { 0 };//用来存放fread读写的信息
    89. while (fread(&tmp, sizeof(PeoInfo), 1, pf))
    90. {
    91. //检查容量
    92. CheckCapacity(pc);
    93. pc->data[pc->sz] = tmp;
    94. pc->sz++;
    95. }
    96. fclose(pf);
    97. pf = NULL;
    98. }
    99. //销毁通讯录
    100. void DestroyContact(contact* pc)
    101. {
    102. free(pc->data);
    103. pc->data = NULL;
    104. pc->sz = 0;
    105. pc->capacity = 0;
    106. }
    107. void ShowContact(contact* pc)
    108. {
    109. assert(pc);
    110. if (pc->sz == 0)
    111. {
    112. printf("通讯录为空\n");
    113. return;
    114. }
    115. printf("%-10s %-5s %-10s %-15s %-10s\n", "名字", "性别", "年龄", "电话", "住址");
    116. int i = 0;
    117. for (i = 0; i < pc->sz; i++)
    118. {
    119. printf("%-10s %-5s %-10d %-15s %-10s\n",
    120. pc->data[i].name, pc->data[i].sex, pc->data[i].age,
    121. pc->data[i].tele, pc->data[i].addr);
    122. }
    123. printf("\n");
    124. }
    125. //静态版本
    126. //void AddContact(contact* pc)
    127. //{
    128. // assert(pc);
    129. // int adds;
    130. //back:
    131. // if (pc->sz == MAX)
    132. // {
    133. // printf("通讯录已满,存入信息失败\n");
    134. // return;
    135. // }
    136. //
    137. // printf("请输入姓名>:");
    138. // scanf("%s", pc->data[pc->sz].name);
    139. // printf("请输入性别>:");
    140. // scanf("%s", pc->data[pc->sz].sex);
    141. // printf("请输入年龄>:");
    142. // scanf("%d", &(pc->data[pc->sz].age));
    143. // printf("请输入电话>:");
    144. // scanf("%s", pc->data[pc->sz].tele);
    145. // printf("请输入住址>:");
    146. // scanf("%s", pc->data[pc->sz].addr);
    147. // pc->sz++;
    148. // printf("信息添加成功\n");
    149. //
    150. // printf("是否继续添加联系人信息1/0:");
    151. // scanf("%d", &adds);
    152. // if (adds == 1)
    153. // goto back;
    154. // else
    155. // {
    156. // return;
    157. // }
    158. //}
    159. //增容函数
    160. void CheckCapacity(contact* pc)
    161. {
    162. if (pc->sz == pc->capacity)
    163. {
    164. PeoInfo* str = (PeoInfo*)realloc(pc->data, (pc->capacity + 5) * sizeof(PeoInfo));
    165. if (str != NULL)
    166. {
    167. pc->data = str;
    168. pc->capacity += 5;
    169. printf("增容成功\n");
    170. }
    171. else
    172. {
    173. perror("CheckCapacity->realloc");
    174. return;
    175. }
    176. }
    177. }
    178. //动态版本
    179. void AddContact(contact* pc)
    180. {
    181. assert(pc);
    182. CheckCapacity(pc);//检查通讯录是否满
    183. int adds;
    184. back:
    185. printf("请输入姓名>:");
    186. scanf("%s", pc->data[pc->sz].name);
    187. printf("请输入性别>:");
    188. scanf("%s", pc->data[pc->sz].sex);
    189. printf("请输入年龄>:");
    190. scanf("%d", &(pc->data[pc->sz].age));
    191. printf("请输入电话>:");
    192. scanf("%s", pc->data[pc->sz].tele);
    193. printf("请输入住址>:");
    194. scanf("%s", pc->data[pc->sz].addr);
    195. pc->sz++;
    196. printf("信息添加成功\n");
    197. printf("是否继续添加联系人信息1/0:");
    198. scanf("%d", &adds);
    199. if (adds == 1)
    200. goto back;
    201. else
    202. {
    203. return;
    204. }
    205. }
    206. //通讯录信息保存
    207. void SaveContact(contact* pc)
    208. {
    209. assert(pc);
    210. //打开文件
    211. FILE* pf = fopen("contact.txt", "wb");
    212. if (pf == NULL)
    213. {
    214. perror("SaveContact");
    215. return 1;
    216. }
    217. //写文件
    218. int i = 0;
    219. for (i = 0; i < pc->sz; i++)
    220. {
    221. fwrite(pc->data + i, sizeof(PeoInfo), 1, pf);//fwrite写文件更方便
    222. }
    223. //关闭文件
    224. fclose(pf);
    225. pf = NULL;
    226. }
    227. //查看某个联系人是否存在
    228. static int FindContact(contact* pc, char name[])
    229. {
    230. assert(pc);
    231. int i = 0;
    232. for (i = 0; i < pc->sz; i++)
    233. {
    234. if (strcmp(name, pc->data[i].name) == 0)
    235. return i;
    236. }
    237. return -1;
    238. }
    239. //删除联系人
    240. void DelContact(contact* pc)
    241. {
    242. assert(pc);
    243. if (pc->sz == 0)
    244. {
    245. printf("通讯录为空,删除失败\n");
    246. return;
    247. }
    248. printf("请输入你要删除的联系人:");
    249. char name[NAME_MAX];
    250. scanf("%s", name);
    251. int ret = FindContact(pc, name);
    252. if (ret == -1)
    253. {
    254. printf("联系人不存在,删除失败\n");
    255. return;
    256. }
    257. int i = 0;
    258. for (i = ret; i < pc->sz - 1; i++)
    259. {
    260. pc->data[i] = pc->data[i + 1];
    261. }
    262. pc->sz--;
    263. printf("删除联系人成功\n");
    264. }
    265. //查找联系人
    266. void SearchContact(contact* pc)
    267. {
    268. assert(pc);
    269. printf("请输入你要查找联系人的名字:");
    270. char name[NAME_MAX];
    271. scanf("%s", name);
    272. int ret = FindContact(pc, name);
    273. if (ret == -1)
    274. {
    275. printf("联系人不存在,查找失败\n");
    276. return;
    277. }
    278. printf("查找成功:\n");
    279. printf("%-10s %-5s %-10s %-15s %-10s\n", "名字", "性别", "年龄", "电话", "住址");
    280. printf("%-10s %-5s %-10d %-15s %-10s\n",
    281. pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
    282. pc->data[ret].tele, pc->data[ret].addr);
    283. }
    284. //修改联系人
    285. void ModifyContact(contact* pc)
    286. {
    287. assert(pc);
    288. printf("请输入你要查找联系人的名字:");
    289. char name[NAME_MAX];
    290. scanf("%s", name);
    291. int ret = FindContact(pc, name);
    292. if (ret == -1)
    293. {
    294. printf("联系人不存在,修改失败\n");
    295. return;
    296. }
    297. printf("联系人存在:");
    298. printf("%-10s %-5s %-10d %-15s %-10s\n",
    299. pc->data[ret].name, pc->data[ret].sex, pc->data[ret].age,
    300. pc->data[ret].tele, pc->data[ret].addr);
    301. printf("请修改姓名>:");
    302. scanf("%s", pc->data[ret].name);
    303. printf("请修改性别>:");
    304. scanf("%s", pc->data[ret].sex);
    305. printf("请修改年龄>:");
    306. scanf("%d", &(pc->data[ret].age));
    307. printf("请修改电话>:");
    308. scanf("%s", pc->data[ret].tele);
    309. printf("请修改住址>:");
    310. scanf("%s", pc->data[ret].addr);
    311. printf("\n修改成功\n");
    312. }
    313. //分类菜单
    314. void menu2()
    315. {
    316. printf("*************************\n");
    317. printf("**** 1.名字 2.年龄 ****\n");
    318. printf("*************************\n");
    319. }
    320. //静态排序
    321. //名字排序
    322. //int qsort_cmp_name(const void* e1, const void* e2)
    323. //{
    324. // return strcmp((((contact*)e1)->data)->name, (((contact*)e2)->data)->name);
    325. //}
    326. 年龄排序
    327. //int qsort_cmp_age(const void* e1, const void* e2)
    328. //{
    329. // return (((contact*)e1)->data)->age - (((contact*)e2)->data)->age;
    330. //}
    331. 联系人排序
    332. //void SortContact(contact* pc)
    333. //{
    334. // int input2;
    335. // menu2();
    336. // printf("请选择排序方式:");
    337. // scanf("%d", &input2);
    338. // switch (input2)
    339. // {
    340. // case 1:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_name); break;
    341. // case 2:qsort(pc->data, pc->sz, sizeof(pc->data[0]), qsort_cmp_age); break;
    342. // defualt:printf("选择错误\n");
    343. // break;
    344. // }
    345. //}
    346. //动态排序
    347. //名字排序
    348. int qsort_cmp_name(const void* e1, const void* e2)
    349. {
    350. return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
    351. }
    352. //年龄排序
    353. int qsort_cmp_age(const void* e1, const void* e2)
    354. {
    355. return ((PeoInfo*)e1)->age - ((PeoInfo*)e2)->age;
    356. }
    357. //联系人排序
    358. void SortContact(contact* pc)
    359. {
    360. int input2;
    361. menu2();
    362. printf("请选择排序方式:");
    363. scanf("%d", &input2);
    364. switch (input2)
    365. {
    366. case 1:qsort(pc->data, pc->sz, sizeof(PeoInfo), qsort_cmp_name); break;
    367. case 2:qsort(pc->data, pc->sz, sizeof(PeoInfo), qsort_cmp_age); break;
    368. defualt:printf("选择错误\n");
    369. break;
    370. }
    371. }
    372. void menu()
    373. {
    374. printf("********************************\n");
    375. printf("**** 1. add 2. del ****\n");
    376. printf("**** 3. search 4. modify ****\n");
    377. printf("**** 5. show 6. sort ****\n");
    378. printf("**** 0. exit ****\n");
    379. printf("********************************\n");
    380. }
    381. enum Option
    382. {
    383. EXIT,//退出
    384. ADD,//增加
    385. DEL,//删除联系人
    386. SEARCH,//查找联系人
    387. MODIFY,//修改指定联系人
    388. SHOW,//打印联系人
    389. SORT,//分类
    390. };
    391. int main()
    392. {
    393. contact con;
    394. InitContact(&con);
    395. int input=0;
    396. do
    397. {
    398. menu();
    399. printf("请输入你的选择>:");
    400. scanf("%d", &input);
    401. switch (input)
    402. {
    403. case ADD:AddContact(&con);
    404. SaveContact(&con);
    405. break;
    406. case DEL:DelContact(&con);
    407. SaveContact(&con);
    408. break;
    409. case SEARCH:SearchContact(&con);
    410. break;
    411. case MODIFY:ModifyContact(&con);
    412. SaveContact(&con);
    413. break;
    414. case SHOW:ShowContact(&con);
    415. break;
    416. case SORT:SortContact(&con);
    417. SaveContact(&con);
    418. break;
    419. case EXIT:SaveContact(&con);//将通讯录保存于文件中
    420. DestroyContact(&con);
    421. printf("你已选择退出程序\n");
    422. break;
    423. default:printf("选择错误,请重新选择\n");
    424. break;
    425. }
    426. } while (input);
    427. return 0;
    428. }

    运行结果:

  • 相关阅读:
    Vue--》如何在Vue3中书写TSX
    JSR303数据校验
    《最新出炉》系列初窥篇-Python+Playwright自动化测试-18-处理鼠标拖拽-上篇
    【.Net实用方法总结】 整理并总结System.IO中File类及其方法介绍
    C语言字符函数和字符串函数(1)
    OpenCV+QT5在Window下的环境配置记录
    python-----发邮件
    20--Django-项目实战-博客开发之终章-文章评论、添加文章功能实现
    虚拟机没有桥接模式--物理机WiFi不见了--注册表修复
    瀑布流布局
  • 原文地址:https://blog.csdn.net/2301_77053417/article/details/133869772