C语言实现通讯录提供增删改查等方法(多文件+动态内存+文件存储联系人数据)

    技术2026-04-07  9

    (动态增加内存初始大小为2每次扩容大小为2(修改宏可更改)+文件存储联系人 数据每次使用时读取文件内容保存在内存中) 编译器 vs2013 通讯录可以用来存储联系人个人的信息,每个人的信息包括:姓 名、性 别、年龄、电话、住址 提供方法: 1.添加联系人信息 2.删除指定联系人信息 3.查找指定联系人信息 4.修改指定联系人信息 5.显示所有联系人信息 6.清空所有联系人 7.以名字排序所有联系人

    mian.c

    #include"test.h" void menu(){ printf("╔═══════════════════════════════════════════════════╗\n"); printf("║═══════════════════ 通讯录 ══════════════════════║\n"); printf("║═══ ═══║\n"); printf("║═══ 1.新建联系人 2.删除联系人 ═══║\n"); printf("║═══ 3.查找联系人 4.修改联系人 ═══║\n"); printf("║═══ 5.清空联系人 6.排序联系人 ═══║\n"); printf("║═══ 7.打印联系人 0.退出 ═══║\n"); printf("║═══ ═══║\n"); printf("╚═══════════════════════════════════════════════════╝\n"); } int main(){ int flag = 1; int select = 0; contact_t *ct=NULL; InitContact(&ct); while (flag){ menu(); int cout = 0; printf("请选择:[0-7]#:\n"); scanf("%d", &select); switch (select){ case 1: AddContact(&ct); break; case 2: DelectContact(ct); break; case 3: SearchContact(ct); break; case 4: ModifyContact(ct); break; case 5: ClearContact(ct); break; case 6: SortContact(ct); break; case 7: PrintContact(ct); break; case 0: printf("欢迎下次使用!!!\n"); SaveContact(ct); Sleep(2000); flag = 0; break; default: printf("输入有误请重新输入!!!!!\n"); break; } } system("pause"); return 0; }

    test.h(头文件)

    #ifndef _TEST_H_ #define _TEST_H_ #include<stdio.h> #include<windows.h> #include<assert.h> #pragma warning(disable:4996) //person内部元素的大小 #define NAME_SIZE 32 #define SEX_SIZE 8 #define TELPHONE_SIZE 16 #define ADDRESS_SIZE 128 #define INIT_NUM 2//通讯录的初始容量 #define INC_NUM 2//扩容大小 //文件信息 #define SAVE_FILE "save.txt" typedef struct person{ char name[NAME_SIZE]; char sex[SEX_SIZE]; int age; char telphone[TELPHONE_SIZE]; char address[ADDRESS_SIZE]; }person_t; typedef struct contact{ int cap;//容量的大小 int size;//当前存储大小 person_t contacts[0];//柔性数组 }contact_t; void AddContact(contact_t **ct); void InitContact(contact_t **ct); void SearchContact(contact_t *ct); void ClearContact(contact_t *ct); void DelectContact(contact_t *ct); void ModifyContact(contact_t *ct); void PrintContact(contact_t *ct); void SortContact(contact_t *ct); void SaveContact(contact_t *ct); #endif

    test.c(函数的实现)

    #include"test.h" void InitContact(contact_t **ct) { /*assert(ct); *ct = (contact_t *)malloc(sizeof(person_t)*INIT_NUM + sizeof(contact_t)); if (ct == NULL){ perror("malloc"); exit(1); } memset(*ct, 0, sizeof(person_t)*INIT_NUM + sizeof(contact_t));//对申请的内存进行初始化 (*ct)->cap = INIT_NUM;*/ FILE *fp = fopen(SAVE_FILE, "rb"); if (fp == NULL){ *ct = (contact_t *)malloc(sizeof(contact_t)+INIT_NUM*sizeof(person_t)); if (*ct == NULL){ perror("malloc"); exit(1); } (*ct)->size = 0; (*ct)->cap = INIT_NUM; printf("Using Default Init!\n"); } else{ contact_t temp; fread(&temp, sizeof(contact_t), 1, fp); *ct = (contact_t *)malloc(sizeof(contact_t)+temp.cap * sizeof(person_t)); if (*ct == NULL){ perror("malloc"); exit(2); } memcpy(*ct, &temp, sizeof(contact_t)); fread((*ct)->contacts, sizeof(person_t), (*ct)->size, fp); printf("Using Sava.txt Init!\n"); fclose(fp); } } static int IsFull(contact_t *ct){ assert(ct); return ct->size == ct->cap; } static int Inc(contact_t **ct){ assert(ct); contact_t *temp = (contact_t*)realloc(*ct,sizeof(contact_t)+((*ct)->cap + INC_NUM)*sizeof(person_t)); if (temp == NULL){ perror("relloc"); return 0; } *ct = temp; (*ct)->cap += INC_NUM; printf("自动扩容成功!!"); return 1; } static IsExist(contact_t *ct, person_t *p){//判断联系人是否存在 assert(ct); assert(p); int i = 0; for (; i < ct->size; i++){ if (strcmp(ct->contacts[i].name, p->name)==0){ return 1; } } return 0; } void AddContact(contact_t **ct){//添加联系人 assert(ct); if (!IsFull(*ct) || Inc(ct)){ person_t p; printf("请输入新增联系人的姓名:\n"); scanf("%s", p.name); printf("请输入新增联系人的性别:\n"); scanf("%s", p.sex); printf("请输入新增联系人的年龄:\n"); scanf("%d", &(p.age)); printf("请输入新增联系人的电话:\n"); scanf("%s", p.telphone); printf("请输入新增联系人的住址:\n"); scanf("%s", p.address); if (IsExist(*ct, &p)){ printf("该联系人已经存在!!"); return; } else{ memcpy((*ct)->contacts + (*ct)->size, &p, sizeof(p));//拷贝 (*ct)->size += 1; } } else{ printf("扩容失败!!"); } } static SearchCore(contact_t *ct, char *str){//返回联系人的下标 int i = 0; for (; i < ct->size; i++){ person_t *p = ct->contacts + i; if (strcmp(str, p->name) == 0){ return i; } } return -1; } void SearchContact(contact_t *ct){//查找联系人 assert(ct); printf("请输入你要查找的联系人的姓名:\n"); char name[NAME_SIZE]; scanf("%s", name); int i = SearchCore(ct, name); if (i+1){ printf("╔═════════════════════════════════════════════════════════════╗\n"); printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║"); printf("%3d\t%6s\t%2d%8s%18s%17s\n", i + 1, ct->contacts[i].name, ct->contacts[i].age, ct->contacts[i].sex, ct->contacts[i].telphone, ct->contacts[i].address); printf("╚═════════════════════════════════════════════════════════════╝\n"); } else{ printf("你要查找的人 %s 不存在!\n", name); } } void ClearContact(contact_t *ct){ assert(ct); Sleep(2000); ct->size = 0; printf("通讯录已经清空\n"); } void DelectContact(contact_t *ct){//删除联系人 assert(ct); char name[NAME_SIZE]; printf("请输入你要删除的联系人姓名:\n"); scanf("%s", name); int ret = SearchCore(ct, name); if (ret){ ct->contacts[ret] = ct->contacts[(ct->size) - 1]; (ct->size) -= 1; } else{ printf("通讯录中没有联系人%s", name); } } void ModifyContact(contact_t *ct){//修改联系人 assert(ct); char name[NAME_SIZE]; printf("请输入你要修改的联系人姓名:\n"); scanf("%s", name); int ret = SearchCore(ct, name); if (ret){ printf("请输入修改后的姓名:\n"); scanf("%s", ct->contacts[ret].name); printf("请输入修改后的年龄:\n"); scanf("%d", ct->contacts[ret].age); printf("请输入修改后的性别:\n"); scanf("%s", ct->contacts[ret].sex); printf("请输入修改后的电话:\n"); scanf("%s", ct->contacts[ret].telphone); printf("请输入修改后的地址:\n"); scanf("%s", ct->contacts[ret].address); printf("原联系人%s修改成功\n", name); } else{ printf("通讯录中没有联系人%s", name); } } static int IsEmpty(contact_t *ct){//判断联系人是否为空 return (ct->size)==0; } void PrintContact(contact_t *ct){//打印联系人 assert(ct); printf("╔═════════════════════════════════════════════════════════════╗\n"); printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║"); for (int i = 0; i < ct->size; i++){ printf("%3d\t%6s\t%2d%8s%18s%17s\n", i + 1, ct->contacts[i].name, ct->contacts[i].age, ct->contacts[i].sex, ct->contacts[i].telphone, ct->contacts[i].address); } printf("╚═════════════════════════════════════════════════════════════╝\n"); } static int Compare(const void *p1, const void *p2){//使用qsort时提供的回调函数 assert(p1); assert(p2); person_t *_p1 = (person_t*)p1; person_t *_p2 = (person_t*)p2; return strcmp(_p1->name, _p2->name); } void SortContact(contact_t *ct){ assert(ct); if (!IsEmpty(ct)){ qsort(ct->contacts, ct->size, sizeof(person_t), Compare); } } void SaveContact(contact_t *ct){//退出时将数据保存到文件中 assert(ct); FILE *fp = fopen(SAVE_FILE, "wb"); if (fp == NULL){ perror("svae error!\n"); return; } fwrite(ct, sizeof(contact_t), 1, fp); fwrite(ct->contacts, sizeof(person_t), ct->size, fp); }

    运行界面:

    Processed: 0.011, SQL: 9