顺序表的应用 --> 简单通讯录的实现

个人主页流年如梦

专栏《C语言》 《数据结构》

文章目录

Ladies and gentlemen,此次我们将要通过我们之前所学的知识一起来学习如何实现简单通讯录,简单实现通讯录将会涉及到的知识点分别有:结构体动态内存管理顺序表文件操作

一.基于动态顺序表实现通讯录

1.1通讯录主要功能要求

  1. 存储至少100人信息
  2. 姓名、性别、年龄、电话、地址
  3. 要有增、删、查、改、显示(核心功能)
  4. 程序退出数据不会丢失(文件需要保存下来)

二.整体结构

分别有:

  1. SeqList.h/c --> 动态顺序表底层
  2. contact.h/c --> 通讯录业务逻辑
  3. test.c --> 测试菜单

三.通讯录的实现

3.1SeqList.h --> 顺序表声明

SeqList.c顺序表的实现在这里👉顺序表

如下所示:

c 复制代码
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"contact.h"

typedef struct PersonInfo SQDataType;

typedef struct SeqList
{
    SQDataType* a;
    int size;
    int capacity;
}SLT;

//基础接口
void SeqListInit(SLT* psl);
void SeqListDesTroy(SLT* psl);
void SeqListPushBack(SLT* psl, SQDataType x);
void SeqListErase(SLT* psl, size_t pos);
int SeqListFind(SLT* psl, SQDataType x);

3.2contact.h --> 通讯录声明

代码参考:

c 复制代码
#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100

typedef struct SeqList contact;

typedef struct PersonInfo
{
    char name[NAME_MAX];
    char sex[SEX_MAX];
    int age;
    char tel[TEL_MAX];
    char addr[ADDR_MAX];
}PeoInfo;

//通讯录接口
void InitContact(contact* con);
void AddContact(contact* con);
void DelContact(contact* con);
void ShowContact(contact* con);
void FindContact(contact* con);
void ModifyContact(contact* con);
void DestroyContact(contact* con);

3.3核心功能(增、删、查、改、显示等)

3.3.1初始化+加载历史数据

c 复制代码
void LoadContact(contact* con)
{
    FILE* pf = fopen("contact.txt", "rb");
    if (pf == NULL)
    {
        perror("fopen");
        return;
    }
    PeoInfo info;
    while (fread(&info, sizeof(PeoInfo), 1, pf))
    {
        SeqListPushBack(con, info);
    }
    fclose(pf);
}

void InitContact(contact* con)
{
    SeqListInit(con);
    LoadContact(con);
}

3.3.2添加联系人 --> "增"

c 复制代码
void AddContact(contact* con)
{
    PeoInfo info;
    printf("请输入姓名:");
    scanf("%s", info.name);
    printf("请输入性别:");
    scanf("%s", info.sex);
    printf("请输入年龄:");
    scanf("%d", &info.age);
    printf("请输入电话:");
    scanf("%s", info.tel);
    printf("请输入地址:");
    scanf("%s", info.addr);

    SeqListPushBack(con, info);
    printf("添加成功!\n");
}

3.3.3删除联系人 --> "删"

c 复制代码
void DelContact(contact* con)
{
    char name[NAME_MAX];
    printf("请输入要删除的姓名:");
    scanf("%s", name);

    int pos = FindByName(con, name);
    if (pos == -1)
    {
        printf("用户不存在\n");
        return;
    }
    SeqListErase(con, pos);
    printf("删除成功!\n");
}

3.3.4按姓名查找 --> "查"

c 复制代码
int FindByName(contact* con, char name[])
{
    for (int i = 0; i < con->size; i++)
    {
        if (strcmp(con->a[i].name, name) == 0)
            return i;
    }
    return -1;
}

3.3.5修改联系人 --> "改"

c 复制代码
void ModifyContact(contact* con)
{
    char name[NAME_MAX];
    printf("请输入要修改的姓名:");
    scanf("%s", name);
    int pos = FindByName(con, name);
    if (pos == -1)
    {
        printf("用户不存在\n");
        return;
    }
    printf("请输入新姓名:");
    scanf("%s", con->a[pos].name);
    printf("请输入新性别:");
    scanf("%s", con->a[pos].sex);
    printf("请输入新年龄:");
    scanf("%d", &con->a[pos].age);
    printf("请输入新电话:");
    scanf("%s", con->a[pos].tel);
    printf("请输入新地址:");
    scanf("%s", con->a[pos].addr);
    printf("修改成功!\n");
}

3.3.6显示所有联系人 -- > "显示"

c 复制代码
void ShowContact(contact* con)
{
    printf("%-10s %-4s %-4s %-15s %-20s\n","姓名", "性别", "年龄", "电话", "地址");
    for (int i = 0; i < con->size; i++)
    {
        printf("%-10s %-4s %-4d %-15s %-20s\n",
            con->a[i].name,
            con->a[i].sex,
            con->a[i].age,
            con->a[i].tel,
            con->a[i].addr);
    }
}

3.3.7退出时保存文件+销毁

c 复制代码
void SaveContact(contact* con)
{
    FILE* pf = fopen("contact.txt", "wb");
    for (int i = 0; i < con->size; i++)
    {
        fwrite(con->a + i, sizeof(PeoInfo), 1, pf);
    }
    fclose(pf);
    printf("保存成功!\n");
}

void DestroyContact(contact* con)
{
    SaveContact(con);
    SeqListDesTroy(con);
}

3.4test.c --> 主函数

代码如下:

c 复制代码
void menu()
{
    contact con;
    InitContact(&con);
    int op = 0;
    do
    {
        printf("1.添加 2.删除 3.查找 4.修改 5.显示 0.退出\n");
        scanf("%d", &op);
        switch (op)
        {
        case 1: AddContact(&con); break;
        case 2: DelContact(&con); break;
        case 3: FindContact(&con); break;
        case 4: ModifyContact(&con); break;
        case 5: ShowContact(&con); break;
        case 0: DestroyContact(&con); break;
        default: printf("输入错误\n");
        }
    } while (op != 0);
}

3.5最终运行结果(截图)

🎯总结

  1. 动态顺序表可以快速实现增删查改的项目
  2. 通讯录 = 顺序表 + 结构体 + 文件操作
  3. 文件读写用fread/fwrite二进制方式,数据可持久化
  4. 顺序表支持随机访问 ,但插入删除低效
  5. 空间浪费、扩容开销是顺序表的硬伤

⚠️易错点

  1. 文件打开忘记判断空指针
  2. 增容忘记判断、导致越界
  3. 删除或插入不判断pos合法性
  4. 字符串比较不用strcmp
  5. 文件名写错导致数据加载或保存失败

👀 关注 我们一路同行,从入门到大师,慢慢沉淀、稳步成长
❤️ 点赞 鼓励原创,让优质内容被更多人看见
⭐ 收藏 收好核心知识点与实战技巧,需要时随时查阅
💬 评论 分享你的疑问或踩坑经历,一起交流避坑、共同进步

相关推荐
如君愿1 小时前
考研复习 Day 31 | 习题--计算机网络 第五章(运输层 中)、数据结构 图 (中)
数据结构·计算机网络·课后习题
嵌入式小杰2 小时前
一阶卡尔曼滤波入门教程:从原理到单片机 C 代码实现
c语言·单片机
weixin_421725262 小时前
C语言已逐渐落伍 什么样的语言能取代C语言?
c语言·编程语言·llvm·替代方案·go和rust
代码地平线2 小时前
【数据结构】二叉树详解:全代码逐行解析+6道LeetCode高频OJ题图解
数据结构·算法·leetcode
三品吉他手会点灯2 小时前
C语言学习笔记 - 26.C编程预备计算机专业知识 - 15~25关键内容回顾
c语言·笔记·学习
聆风吟º2 小时前
【C标准库】深入理解C语言pow函数:从入门到精通,一文搞定幂运算
c语言·开发语言·库函数·pow·幂运算
流年如夢2 小时前
顺序表(LeetCode)
c语言·数据结构·leetcode·职场和发展
say_fall2 小时前
校招必看:八大排序算法原理、复杂度与高频面试题
数据结构·c++·算法·排序算法
SunnyByte14 小时前
C语言——贪吃蛇的实现
c语言·单链表·贪吃蛇