前言
本次是通讯录的本地实现,可以将程序中输入信息保存到当地文件"test.dat"再次打开程序依旧会打开test.dat文件从而做到本地保存文件。
正文
正文我会将源码呈现出来并以注释的形势进行部分讲解。本次通讯录是对前面知识的一个很好的总结,舒文建议大家也跟着敲一敲。😁
test.c 部分
主要实现代码逻辑等:
#include"contact.h" void menu() { printf("*********************************\n"); printf("*****1.ADD 2.DEL 3.SEARCH****\n"); printf("*****4.MODIFY 5.SHOW 6.SORT******\n"); printf("*****7.CLEAR_EVERY 0.EXIT ******\n"); printf("*********************************\n"); printf("*********************************\n"); } enum Opinion { EXIT, ADD, DEL, SEARCH, MODIFY, SHOW, SORT, CLEAR_EVERY, }; int main() { contact con = { 0 }; //结构体初始化 InitContact(&con); //功能实现 int input = 0; do { menu(); printf("请输入想要的功能:>"); scanf("%d", &input); switch(input)//通讯录功能 { case ADD: AddContact(&con); break; case SORT: SortContact(&con); break; case DEL: DelContact(&con); break; case CLEAR_EVERY: Clear_Every(&con); break; case SHOW: ShowContact(&con); break; case MODIFY: ModifyContact(&con); break; case SEARCH: SearchContact(&con); break; case EXIT: SaveContact(&con);//将信息保存到文件中,关闭文件并将文件指针NULL化 DestoryContact(&con);//动态指针NULL化free动态内存 printf("退出成功"); break; default: printf("输入错误\n"); break; } } while (input); return 0; }
contact.c 部分
这部分内容主要是对函数功能的实现,源码发给大家了,个人感觉这个没啥难点。(当然也有博主懒的一方面在)
#include"contact.h" void LoadContact(contact* pc) { FILE* p = fopen("contact.dat", "r"); if (p == NULL) { perror("LoadContact"); return; } PeoInfo tmp = { 0 };//这个临时变量是为了调整顺序。 //当然也可以通过调节pc->sz++的位置来省掉这个临时变量。 while (fread(&tmp, sizeof(PeoInfo), 1, p)) { CheckContact(pc); pc->date[pc->sz] = tmp; pc->sz++; } fclose(p); p = NULL; } void InitContact(contact* pc) { assert(pc); pc->date = (PeoInfo*)calloc(CAPACITY_SZ, sizeof(PeoInfo)); if (pc->date == NULL) { perror("InitContact"); return; } pc->capacity = CAPACITY_SZ; pc->sz = 0; LoadContact(pc); } void CheckContact(contact* pc) { if (pc->sz == pc->capacity) { PeoInfo* ptr = realloc(pc->date, sizeof(PeoInfo) * (pc->capacity + ADD_SZ)); if (ptr != NULL) { pc->date = ptr; printf("增容成功\n"); pc->capacity += ADD_SZ; } else { printf("增容失败"); perror("CheckContact"); } } } void AddContact(contact* pc)//增加人数 { CheckContact(pc);//检查通讯录是否已被占满并实现占满增加 printf("请输入姓名:>\n"); scanf("%s", pc->date[pc->sz].name); printf("请输入电话\n"); scanf("%s", pc->date[pc->sz].tel); printf("请输入年龄:>\n"); scanf("%d", &pc->date[pc->sz].age); printf("请输入性别>:\n"); scanf("%s", pc->date[pc->sz].sex); printf("请输入地址>:\n"); scanf("%s", pc->date[pc->sz].address); (pc->sz)++; printf("增加成功\n"); } void ShowContact(contact* pc) { int i = 0; //打印标题 printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址"); //打印数据 for (i = 0; i < pc->sz; i++) { printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->date[i].name, pc->date[i].age, pc->date[i].sex, pc->date[i].tel, pc->date[i].address); } } int cmp(const void* p1,const void* p2) { return (strcmp(((PeoInfo*)p1)->name, ((PeoInfo*)p2)->name)); } void SortContact(contact* pc) { qsort(pc->date, pc->sz, sizeof(pc->date[0]), cmp); printf("排序成功\n"); ShowContact(pc); } int FindContact(contact* pc,char* name) { for (int i = 0; i < pc->sz; i++) { if (strcmp(pc->date[i].name, name) == 0) { return i; } } return -1; } void DelContact(contact* pc) { char name[NAME_MAX] = { 0 }; assert(pc); if (pc->sz == 0) { printf("姐姐您没人能删了"); return; } printf("请输入要删除人的姓名>:"); scanf("%s", name); int pos = FindContact(pc,name); if (-1 == pos) { printf("联系人不存在\n"); return; } int i = 0; for (i = pos; i < pc->sz; i++) { pc->date[i] = pc->date[i + 1]; } pc->sz--; printf("删除成功\n"); } void Clear_Every(contact* pc) { assert(pc); printf("您确定吗?\n输入1以确定您的选择\n"); int input = 0; scanf("%d", &input); if (1 == input) { pc->date = (PeoInfo*)calloc(CAPACITY_SZ, sizeof(PeoInfo)); if (pc->date == NULL) { perror("Clear_Every"); return; } pc->capacity = CAPACITY_SZ; pc->sz = 0; printf("清除成功"); } else { printf("您的联系人还在\n"); return; } } void ModifyContact(contact* pc) { printf("请输入要改变人的姓名>:\n"); char name[NAME_MAX] = { 0 }; scanf("%s", name); int por = FindContact(pc, name); if (-1 == por) { printf("联系人不存在\n"); return; } printf("请重新输入改后的信息\n"); printf("请输入姓名:>\n"); scanf("%s", pc->date[por].name); printf("请输入电话\n"); scanf("%s", pc->date[por].tel); printf("请输入年龄:>\n"); scanf("%d", &pc->date[por].age); printf("请输入性别>:\n"); scanf("%s", pc->date[por].sex); printf("请输入地址>:\n"); scanf("%s", pc->date[por].address); (pc->sz)++; printf("改变成功\n"); } void SearchContact(contact* pc) { char name[NAME_MAX] = { 0 }; printf("请输入要找人的姓名"); scanf("%s", name); int por = FindContact(pc, name); if (-1 == por) { printf("未找到联系人\n"); return; } printf("%-20s\t%-5s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址"); printf("%-20s\t%-5d\t%-5s\t%-12s\t%-20s\n", pc->date[por].name , pc->date[por].age, pc->date[por].sex, pc->date[por].tel, pc->date[por].address); } void DestoryContact(contact* pc) { free(pc->date); pc->date = NULL; pc->sz = 0; pc->capacity = 0; } void SaveContact(contact* pc) { FILE* p = fopen("contact.dat", "w"); if (p == NULL) { perror("SaveContact"); return; } int i = 0; for (i = 0; i < pc->sz; i++) { fwrite(pc->date + i, sizeof(PeoInfo), 1, p); } fclose(p); p = NULL; }
contact.h 部分
此部分就只是对函数声明一下和结构体的创建等。
#pragma once #include<stdio.h> #include<stdlib.h> #include<assert.h> #include<string.h> #define NAME_MAX 20 #define SEX_MAX 10 #define TEL_MAX 20 #define ADRESS_MAX 30 #define PEOPLE_MAX 5 #define CAPACITY_SZ 5 #define ADD_SZ 3 //姓名、性别、年龄、电话、住址 typedef struct PeoInfo { char name[NAME_MAX]; char sex[SEX_MAX]; int age; char tel[TEL_MAX]; char address[ADRESS_MAX]; }PeoInfo;//存放一个人的结构体 typedef struct contact { PeoInfo* date;//动态管理需要使用指针 int sz;//有效人数个数 int capacity;//用于存放容量 }contact; void InitContact(contact* pc);//对contact进行初始化 void AddContact(contact* pc);//ADD功能的实现 void ShowContact(contact* pc);//SHOW功能的实现 void SortContact(contact* pc);//排序功能的实现 void DelContact(contact* pc);//删除功能的实现 void Clear_Every(contact* pc);//清楚所有人的实现 void DestoryContact(contact* pc);//对开辟空间的NULL化 void SearchContact(contact* pc);//查找人员功能实现 void ModifyContact(contact* pc);//改变人员的实现 void SaveContact(contact* pc);//保存通讯录 void CheckContact(contact* pc);//检查通讯录空间并实现增容
结尾
有一说一这个博客挺水的,但是写代码的时候还是挺煎熬的。并且此次代码是对之前内容的总和,及运用了动态内存的分配又运用了文件部分的内容。是一个不错的练手代码😁。