前言
本文将详细分析一个功能完备的C语言通讯录管理系统,涵盖动态扩容、文件存储、用户登录等核心功能,并提供完整实现思路和代码解析。
一、项目概述
这个通讯录管理系统是一个综合性的C语言项目,实现了以下核心功能:
-
基本通讯录功能:添加、删除、修改、查询、打印、排序联系人
-
用户系统:注册、登录、找回密码
-
文件存储:通讯录数据和用户数据的持久化存储
-
界面设计:心形欢迎界面、系统时间显示
-
动态扩容:根据联系人数量自动调整存储空间
二、系统架构设计
文件结构
contact.h # 通讯录结构体和函数声明
contact.c # 通讯录核心功能实现
New contact.h # 用户系统结构体和函数声明
New contact.c # 用户系统功能实现
main.c # 程序入口和主流程
users.txt # 用户数据存储文件
contact.dat # 通讯录数据存储文件
核心数据结构
// 联系人信息
struct PeoInfo {char name[MAX_NAME]; // 姓名char phone[MAX_PHONE]; // 电话char sex[MAX_SEX]; // 性别char address[MAX_ADDRESS]; // 地址int age; // 年龄
};// 通讯录结构
struct contact {struct PeoInfo* data; // 联系人数组指针int size; // 当前联系人数量int capacity; // 通讯录容量
};// 用户信息
typedef struct The_users {char id[11]; // 账号char pwd[20]; // 密码char name[15]; // 姓名char sex; // 性别long phone; // 电话
} users;
三、核心功能实现
1. 动态扩容机制
通讯录采用动态数组实现,当联系人数量达到当前容量时自动扩容:
#define DEFAULT_SZ 3 // 默认容量void CheckCapacity(struct contact* ps) {if (ps->size == ps->capacity) {// 每次增加2个位置的容量struct PeoInfo* ptr = realloc(ps->data, (ps->capacity + 2) * sizeof(struct PeoInfo));if (ptr != NULL) {ps->data = ptr;ps->capacity += 2;printf("增容成功!\n");} else {printf("增容失败!\n");}}
}
2. 文件存储与加载
通讯录数据持久化存储,程序启动时自动加载数据:
// 保存通讯录到文件
void Save_Contact(struct contact* ps) {FILE* pfWrite = fopen("contact.dat", "wb");if (pfWrite == NULL) {perror("Save_Contact");return;}for (int i = 0; i < ps->size; i++) {fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite);}fclose(pfWrite);
}// 从文件加载通讯录
void Load_Contact(struct contact* ps) {FILE* pfRead = fopen("contact.dat", "rb");if (pfRead == NULL) {return; // 文件不存在时不报错}struct PeoInfo tmp = {0};while (fread(&tmp, sizeof(tmp), 1, pfRead)) {CheckCapacity(ps); // 确保容量足够ps->data[ps->size] = tmp;ps->size++;}fclose(pfRead);
}
3. 用户系统实现
用户注册流程
void registers() {users a, b;FILE* fp = fopen("users.txt", "r");// 检查账号是否已存在printf("请输入账号(六位数账号)\n");scanf("%s", a.id);while (fread(&b, sizeof(users), 1, fp)) {if (strcmp(a.id, b.id) == 0) {printf("此用户名已存在!\n");fclose(fp);return;}}fclose(fp);// 收集用户信息printf("请输入姓名:\n");scanf("%s", a.name);// 性别验证do {printf("请输入性别(f(女)/m(男)):\n");scanf(" %c", &a.sex);} while(a.sex != 'f' && a.sex != 'm');printf("请输入电话号码:\n");scanf("%ld", &a.phone);// 密码确认char temp[20];do {printf("请输入密码(六位数字)\n");scanf("%s", a.pwd);printf("请确认密码\n");scanf("%s", temp);} while(strcmp(a.pwd, temp) != 0);// 保存用户信息fp = fopen("users.txt", "a");fwrite(&a, sizeof(users), 1, fp);fclose(fp);printf("账号注册成功!\n");
}

用户登录流程
void Input_login() {users a, b;FILE* fp = fopen("users.txt", "r");printf("请输入账号\n");scanf("%s", a.id);// 查找用户while (fread(&b, sizeof(users), 1, fp)) {if (strcmp(a.id, b.id) == 0) {// 验证密码do {printf("请输入密码:\n");scanf("%s", a.pwd);if (strcmp(a.pwd, b.pwd) == 0) {fclose(fp);In(); // 进入通讯录主界面return;} else {printf("密码不正确!\n");}} while(1);}}printf("此用户名不存在!\n");fclose(fp);
}

4. 通讯录核心功能
联系人添加
void Add_Contacter(struct contact* ps) {CheckCapacity(ps); // 确保容量足够printf("请输入名字:");scanf("%s", ps->data[ps->size].name);printf("请输入年龄:");scanf("%d", &ps->data[ps->size].age);printf("请输入性别:");scanf("%s", ps->data[ps->size].sex);printf("请输入电话:");scanf("%s", ps->data[ps->size].phone);printf("请输入地址:");scanf("%s", ps->data[ps->size].address);ps->size++;printf("添加成功!\n");
}

联系人查询
void Find_Contacter(const struct contact* ps) {char name[MAX_NAME];printf("请输入你要查找的联系人的姓名:");scanf("%s", name);for (int i = 0; i < ps->size; i++) {if (strcmp(ps->data[i].name, name) == 0) {printf("%-20s\t%-4s\t%-5s\t%-12s\t%-20s\n", "姓名", "年龄", "性别", "电话", "地址");printf("%-20s\t%-4d\t%-5s\t%-12s\t%-20s\n", ps->data[i].name,ps->data[i].age,ps->data[i].sex,ps->data[i].phone,ps->data[i].address);return;}}printf("要查找的人不存在!\n");
}

联系人排序
// 按姓名排序
int Conpare_ByName(const void *e1, const void *e2) {return strcmp(((struct PeoInfo*)e1)->name, ((struct PeoInfo*)e2)->name);
}// 按年龄排序
int Conpare_ByAge(const void* e1, const void* e2) {return ((struct PeoInfo*)e1)->age - ((struct PeoInfo*)e2)->age;
}void Sort_Contacter(struct contact* ps) {printf("请选择排序方式:\n1.姓名\n2.年龄\n3.住址\n");int input;scanf("%d", &input);switch (input) {case 1:qsort(ps->data, ps->size, sizeof(struct PeoInfo), Conpare_ByName);break;case 2:qsort(ps->data, ps->size, sizeof(struct PeoInfo), Conpare_ByAge);break;case 3:qsort(ps->data, ps->size, sizeof(struct PeoInfo), Conpare_ByAddress);break;default:printf("无效选择\n");return;}printf("排序成功!\n");
}
按照姓名排序

按照年龄排序

按照住址排序

5. 图形界面设计
心形欢迎界面
void paintheart() {float y, x, a;for (y = 1.5f; y > -1.5f; y -= 0.1f) {for (x = -1.5f; x < 1.5f; x += 0.05f) {a = x * x + y * y - 1;putchar(a * a * a - x * x * y * y * y <= 0.0f ? '*' : ' ');}putchar('\n');}
}
系统时间显示
void showtime() {time_t timep;struct tm *p;time(&timep);p = localtime(&timep);printf("现在是 %d年%02d月%02d日 %02d:%02d:%02d\n", 1900 + p->tm_year, 1 + p->tm_mon,p->tm_mday,p->tm_hour,p->tm_min,p->tm_sec);
}

四、项目亮点与改进方向
项目亮点
-
模块化设计:清晰分离通讯录核心功能和用户系统
-
动态内存管理:智能扩容机制避免内存浪费
-
数据持久化:文件存储确保数据不丢失
-
用户友好界面:图形化界面提升用户体验
-
健壮性设计:关键操作增加输入验证
改进方向
-
密码加密存储:当前明文存储存在安全隐患
-
批量操作支持:添加批量导入/导出功能
-
模糊搜索:实现基于部分信息的联系人查找
-
数据备份机制:定期自动备份通讯录数据
-
跨平台支持:使用跨平台库增强可移植性
五、使用指南
-
初始账号:123456
-
初始密码:123789
-
编译运行:
gcc main.c contact.c "New contact.c" -o contact
./contact
六、总结
这个C语言通讯录项目综合运用了结构体、指针、文件操作、动态内存管理等核心技术,实现了功能较为完备的通讯录管理系统。通过模块化设计和良好的用户体验,展示了C语言在系统级应用开发中的强大能力。项目代码结构清晰,注释完善,可以作为大家在进行C语言项目开发的参考范例。也欢迎大家一起讨论改进项目。