本次更新了内存自动扩容以及简单的文件操作
#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct liaison { //总会有一些名字占了很大的空间 char name[1024]; //实际上这个类型也避免不了电话号码的溢出 unsigned long phone; }liaison; typedef struct address_list { //指向动态分配的内存的指针 liaison* address; //当前指针指向空间的最大容量 int cap; int size; }address_list; //全局变量,如果在真的开发中它可能真的有用 //现在你把它写到主函数里也无所谓 address_list list; enum { ADD = 1, DEL, MODIFY, ALL, EXIT, }; //EXE窗口中的面板,随你心意设计 //没什么难度 void print_front() { printf("请选择您要进行的操作:\n"); printf("1.添加联系人\n"); printf("2.删除联系人\n"); printf("3.修改联系人\n"); printf("4.所有联系人\n"); printf("5.退出通讯录\n"); } void add(address_list* p, FILE* fp) { //将新加入的内容写入list printf("请输入联系人名称:>>"); scanf("%s", p->address[p->size].name); printf("请输入联系人号码:>>"); scanf("%d", &(p->address[p->size].phone)); //将添加的东西写入文件当中 fprintf(fp, "%d %s %d\n", p->size, p->address[p->size].name, p->address[p->size].phone); p->size++; //当动态分配的内存存满的时候 if (p->size == p->cap) { //每次添加十个liaison的空间 p->cap += 10; //重新分配内存 p->address = (liaison*)realloc(p->address, list.cap * sizeof(liaison)); } } void del(address_list* p, FILE* fp) { int i = 0; printf("请输入删除联系人的编号:"); scanf("%d", &i); //判断我们的目标是否存在 if (i > (p->size)) { printf("您的输入有误"); } for (; i < (p->size); i++) { p->address[i] = p->address[i + 1]; } p->size--; //关闭当前的文件 fclose(fp); //删除我们原本的文件 int ret = remove("D:\\demo\\address_list.txt"); //判断是否删除成功了 if (ret == 0) { printf("文件删除成功"); } else { printf("错误:不能删除该文件"); //你自己看着办吧 system("pause"); } //再次创建一个新的同名的文件 fp = fopen("D:\\demo\\address_list.txt", "a+"); //将我们存在内存中的内容写入新的文件之中 for (int i = 0; i < p->size; i++) { fprintf(fp, "%d %s %d\n", i, p->address[i].name, p->address[i].phone); } } void modify(address_list* p, FILE* fp) { int i = 0; printf("请输入您要修改的联系人编号:"); scanf("%d", &i); if (i > (p->size)) { printf("您的输入有误"); } printf("请输入联系人名称:>>"); scanf("%s", p->address[i].name); printf("请输入联系人号码:>>"); scanf("%d", &(p->address[i].phone)); //和上一个函数几乎一样的操作,我也就不多赘述了 fclose(fp); int ret = remove("D:\\demo\\address_list.txt"); if (ret == 0) { printf("文件删除成功"); } else { printf("错误:不能删除该文件"); system("pause"); } fp = fopen("D:\\demo\\address_list.txt", "a+"); for (int i = 0; i < p->size; i++) { fprintf(fp, "%d %s %d\n", i, p->address[i].name, p->address[i].phone); } } void all(address_list* p, FILE* fp) { //将我们动态内存中存储的信息全部写出来 for (int i = 0; i < (p->size); i++) { printf("[ %d ]\t", i); printf("%s\t", (p->address[i].name)); printf("%d\n", (p->address[i].phone)); } } void player(FILE* fp) { //为了避免输入英文而导致的惨剧 char ser_f[10]; scanf("%s", &ser_f); int ser = atoi(ser_f); switch (ser) { case 0: printf("恭喜你,什么都没有发生"); break; case ADD: add(&list, fp); break; case DEL: del(&list, fp); break; case MODIFY: modify(&list, fp); break; case ALL: all(&list, fp); break; case EXIT: fclose(fp); exit(0); default: printf("您的输入错误"); } } void read_book(address_list* p, FILE* fp) { rewind(fp); int num1 = 0; char name[1024]; int phone = 0; for (int k = 0; k < 512; k++) { //为了避免一些奇奇怪怪的读取 fscanf(fp, "%d %s %d", &num1, name, &phone); //printf("%d %s %d\n", num1, name, phone); if ((k != 0 && num1 == 0) || name == NULL || phone == 0) { break; } p->size = num1; strcpy(p->address[p->size].name, name); p->address[p->size].phone = phone; p->size++; } } int main() { FILE* fp = fopen("D:\\demo\\address_list.txt", "a+"); if (fp == NULL) { puts("Fail to open file!"); exit(0); } list.cap = 100; //开辟空间 list.address = (liaison*)malloc(list.cap * sizeof(liaison)); read_book(&list, fp); print_front(); while (1) { player(fp); } return 0; }