今天学完了c语言,这是我编写的通讯录管理系统,亲测有效,没有问题:
基本功能有:
1、添加联系人
2、查找一个联系人
3、修改联系人
4、删除一个联系人
5、展示所有联系人
6、清空所有联系人
7、以名字排序所有联系人
此外,此程序还支持动态扩容和文件操作(保存和读取功能),注意文件位置,得先创建。这里还有一点需要注意,我在对文件操作的时候直接复制了它的路径,结果程序报错,后来把‘’改成了‘/’就可以了。
#define _CRT_SECURE_NO_WARNINGS #include#include #include #include #include //描述了一个联系人 typedef struct linkman { char name[1024]; char gender[1024]; char age[1024]; char number[1024]; char address[1024]; }linkman; //描述了一个通讯录,里面包含了多个联系人,size是当前联系人数 typedef struct AddressList { //把这个数组改成指针,通过malloc来动态分配内存 linkman* persons; //表示当前这个指针指向的数组的最大容量 int capacity; int size; }AddressList; //创建一个全局变量 AddressList addressList; //保存内容到文件(存档) void save(AddressList* list) { FILE* fp = fopen("E:/address_list.txt", "w"); //查看是否打开成功 if (fp == NULL) { printf("打开存档文件失败n"); return; } //使用fwrite来写 fwrite(list->persons, sizeof(linkman), list->size, fp); fclose(fp); printf("存档成功n"); } //函数声明 //extern void save(AddressList* list); //把文件中数据加载到内存中(读档) void load(AddressList* list) { FILE* fp = fopen("E:/address_list.txt", "r"); if (fp == NULL) { printf("打开存档文件失败n"); return; } //写文件中,一共要读多少个元素,直接通过size就知道了 //读文件中,一共要读多少元素就不好确定,只能一个一个读,直到读到文件末尾 while (1) { if (list->size > list->capacity) { list->capacity += 100; list->persons = realloc(list->persons, sizeof(linkman) * list->capacity); } size_t n = fread(&list->persons[list->size], sizeof(linkman), 1, fp); if (n == 0) { //读到文件末尾了 break; } list->size++; } fclose(fp); printf("读档成功!n"); } //初始化 void init(AddressList* list) { list->size = 0; list->capacity = 100; list->persons = (linkman*)malloc(sizeof(linkman) * list->capacity); //(list->num).name = { 0 }; } int menu() { printf("+----------------------------+n"); printf("| 通讯录管理系统 |n"); printf("+----------------------------+n"); printf("| 1、添加联系人 |n"); printf("| 2、查找一个联系人 |n"); printf("| 3、修改联系人 |n"); printf("| 4、删除联系人 |n"); printf("| 5、展示所有联系人 |n"); printf("| 6、清空所有联系人 |n"); printf("| 7、以名字排序所有联系人 |n"); printf("| 0、退出 |n"); printf("+----------------------------+n"); printf("请输入你的选择:"); int choice = 0; scanf("%d", &choice); return choice; } //添加联系人 void insert(AddressList* list) { assert(list != NULL); //通讯录满了的话就返回 //进行扩容 if (list->size > list->capacity) { list->capacity += 100; list->persons = (linkman*)realloc(list->persons, sizeof(linkman) * list->capacity); } linkman person = { 0 }; printf("请输入联系人姓名:"); scanf("%s", person.name); printf("请输入联系人性别:"); scanf("%s", person.gender); printf("请输入联系人年龄:"); scanf("%s", person.age); printf("请输入联系人电话:"); scanf("%s", person.number); printf("请输入联系人住址:"); scanf("%s", person.address); //把联系人放在通讯录中 list->persons[list->size] = person; list->size++; printf("新增联系人成功n"); //Sleep(2000); //显示两秒 //system("cls"); save(list); } //修改联系人 void change(AddressList* list) { int id = 0; printf("请输入你要修改的联系人的序号:"); scanf("%d", &id); if (id < 0 || id > list->size - 1) { printf("你的输入有误"); return; } linkman* p = &list->persons[id]; printf("请输入修改后的联系人的姓名:"); scanf("%s", p->name); printf("请输入修改后的联系人的性别:"); scanf("%s", p->gender); printf("请输入修改后的联系人的年龄:"); scanf("%s", p->age); printf("请输入修改后的联系人的电话:"); scanf("%s", p->number); printf("请输入修改后的联系人的住址:"); scanf("%s", p->address); printf("修改联系人成功!n"); save(list); } //查找联系人 void find(AddressList* list) { int id = 0; printf("请输入要查看联系人的序号:"); scanf("%d", &id); if (id < 0 || id > list->size - 1) { printf("你的输入有误"); return; } for (int i = 0; i < list->size; i++) { if (id == i) { linkman* p = &list->persons[i]; printf("姓名:%st性别:%st年龄:%st电话:%st住址:%sn", p->name, p->gender, p->age, p->number, p->address); printf("%s", list->persons[i].name); } } } //查看所有联系人 void show(AddressList* list) { //printf("查看所有联系人n"); for (int i = 0; i < list->size; i++) { linkman* p = &list->persons[i]; printf("[%d]t%st%sn", i, p->name, p->number); } printf("一共有%d个联系人n", list->size); } //清空所有联系人 void empty(AddressList* list) { int i = 0; printf("确定要清空所有联系人吗,确定请按1,按其余键返回n"); scanf("%d", &i); if (i == 1) { list->size = 0; printf("删除成功!n"); } return; save(list); } //按照姓名排序 void sort(AddressList* list) { for (int i = 0; i < list->size - 1; i++) { for (int j = 0; j < list->size - 1 - i; j++) { linkman* p1 = &list->persons[j]; linkman* p2 = &list->persons[j + 1]; if (memcmp(p1->name, p2->name, sizeof(p1->name)) > 0) { linkman tmp = list->persons[j]; list->persons[j] = list->persons[j + 1]; list->persons[j + 1] = tmp; } } } printf("排序成功!n"); save(list); } //删除一个联系人(逻辑删除) void update(AddressList* list) { int id = 0; printf("请输入要删除的联系人的序号:n"); scanf("%d", &id); if (id < 0 || id > list->size) { printf("你的输入有误n"); return; } else if (id == list->size - 1) {//要删除的是最后一个联系人 list->size--; printf("删除成功!n"); } //取出最后一个联系人的地址 linkman* p = &list->persons[list->size - 1]; list->persons[id] = *p; list->size--; printf("删除成功!n"); save(list); } //定义一个函数指针 typedef void(*Func)(AddressList*); int main() { init(&addressList); //定义一个函数指针数组 load(&addressList);//程序启动前进行一次读档即可 //为了降低圈复杂度,采用转移表的方式 Func func[] = { NULL,insert,find,change,update,show,empty,sort };//NULL纯粹为了占位 while (1) { int choice = menu(); if (choice == 0) { printf("goodbyen"); break; } else if (choice < 0 || choice > 7) { printf("你的输入有误,请重新输入n"); continue; } func[choice](&addressList); system("pause"); system("cls"); //Func func = func[choice] //func(&addressList) } system("pause"); //当前这个数组的生命周期本就应该跟随整个程序,既然这个数组一直不需要用,就不能提前释放 //当程序结束,内存会被系统自动回收 }
如果有什么问题,欢迎大家指出!



