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

发布于:2025-07-03 ⋅ 阅读:(26) ⋅ 点赞:(0)

前言

    本文将详细分析一个功能完备的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语言项目开发的参考范例。也欢迎大家一起讨论改进项目。


网站公告

今日签到

点亮在社区的每一天
去签到