C语言实现通讯录管理系统:动态扩容、文件存储与用户登录

前言

    本文将详细分析一个功能完备的C语言通讯录管理系统,涵盖动态扩容、文件存储、用户登录等核心功能,并提供完整实现思路和代码解析。

一、项目概述

这个通讯录管理系统是一个综合性的C语言项目,实现了以下核心功能:

  1. 基本通讯录功能:添加、删除、修改、查询、打印、排序联系人

  2. 用户系统:注册、登录、找回密码

  3. 文件存储:通讯录数据和用户数据的持久化存储

  4. 界面设计:心形欢迎界面、系统时间显示

  5. 动态扩容:根据联系人数量自动调整存储空间

二、系统架构设计

文件结构

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);
}

四、项目亮点与改进方向

项目亮点

  1. 模块化设计:清晰分离通讯录核心功能和用户系统

  2. 动态内存管理:智能扩容机制避免内存浪费

  3. 数据持久化:文件存储确保数据不丢失

  4. 用户友好界面:图形化界面提升用户体验

  5. 健壮性设计:关键操作增加输入验证

改进方向

  1. 密码加密存储:当前明文存储存在安全隐患

  2. 批量操作支持:添加批量导入/导出功能

  3. 模糊搜索:实现基于部分信息的联系人查找

  4. 数据备份机制:定期自动备份通讯录数据

  5. 跨平台支持:使用跨平台库增强可移植性

五、使用指南

  1. 初始账号:123456

  2. 初始密码:123789

  3. 编译运行

gcc main.c contact.c "New contact.c" -o contact
./contact

六、总结

    这个C语言通讯录项目综合运用了结构体、指针、文件操作、动态内存管理等核心技术,实现了功能较为完备的通讯录管理系统。通过模块化设计和良好的用户体验,展示了C语言在系统级应用开发中的强大能力。项目代码结构清晰,注释完善,可以作为大家在进行C语言项目开发的参考范例。也欢迎大家一起讨论改进项目。