【C/C++数据结构与算法】C语言通讯录

目录

contact.h头文件

contact.c源文件

main.c源文件


项目分析:

  • 通讯录项目需要用到的顺序表的数据结构,每个元素为一个联系人信息结构体
  • 通讯录功能有新增、删除、查找、修改、排序、打印、清空
  • 通讯录还要有读档和存档的功能,用文件的读写
  • 新增数据要考虑顺序容量问题,若满则扩
  • 删除数据要先找到数据,再从要删除数据的位置,循环将后面的数据前移覆盖
  • 查找数据用strstr比strcmp更好,这样能实现模糊查找
  • 排序用qsort函数,可以按照联系人姓名或者联系人电话号码进行排序

contact.h头文件

外部头文件包含:

#pragma once 
#include 
#include 
#include 
#include 
#include 
#include 

数据结构:

#define CAPACITY 4    //顺序表初始容量

typedef struct PeoInfo 
{
    char name[10];
    char phone[12];
}Peo;

typedef struct Contact 
{
    Peo* data;
    int size;
    int capacity;
}Con;

函数声明:

void Init(Con* con);    //初始化
void Add(Con* con);     //添加
void Del(Con* con);     //删除
void Find(Con* con);    //查找
void Mod(Con* con);     //修改
void Sort(Con* con);    //排序
void Print(Con* con);   //打印
void Destory(Con* con); //清空
void Load(Con* con);    //加载信息
void Save(Con* con);    //保存信息

contact.c源文件

void Init(Con* con) 初始化

#include "contact.h"

void Init(Con* con) 
{
    assert(con);
    con->data = (Peo*)malloc(sizeof(Peo) * CAPACITY);
    if (con->data == NULL) 
    {
        perror("init::malloc");
        exit(1);
    }
    con->size = 0;
    con->capacity = CAPACITY;
    Load(con);    //读档
}

void Add(Con* con)

void Del(Con* con) 数据增删

用临时变量结构体指针进行扩容,增加安全性

bool Empty(Con* con) 
{
    assert(con);
    return con->size == 0;
}    //判空

void Check(Con* con) 
{
    assert(con);
    if (con->size == con->capacity) 
    {
        Peo* tmp = (Peo*)realloc(con->data, sizeof(Peo) * (con->size + CAPACITY));
        if (tmp) 
        {
            con->data = tmp;
            con->capacity += CAPACITY;
        }
    }
}    //检查容量

void Add(Con* con) 
{
    assert(con);
    Check(con);
    printf("请输入姓名:");
    scanf("%s", con->data[con->size].name);
    printf("请输入号码:");
    scanf("%s", con->data[con->size].phone);
    printf("新增联系人成功:%s %s\n", con->data[con->size].name, con->data[con->size].phone);
    ++con->size;
}

void Del(Con* con) 
{
    assert(con);
    if (Empty(con)) 
    {
        printf("通讯录为空\n");
        return;
    }
    printf("请输入要删除的联系人姓名:");
    char del[20];
    scanf("%s", del);
    int i = 0;
    while (i < con->size) 
    {
        if (strcmp(del, con->data[i].name) == 0) 
        {
            int j = i;
            while (j < con->size - 1) 
            {
                strcpy(con->data[j].name, con->data[j + 1].name);
                strcpy(con->data[j].phone, con->data[j + 1].phone);
                ++j;
            }
        }
        ++i;
    }
}

void Find(Con* con) 模糊查询

void Find(Con* con) 
{
    assert(con);
    printf("请输入姓名/号码进行查询:");
    char find[20];
    scanf("%s", find);
    int count = 0;
    int i = 0;
    while (i < con->size) 
    {
        if (strstr(con->data[i].name, find) || strstr(con->data[i].phone, find)) 
        {
            printf("%10s %12s\n", con->data[i].name, con->data[i].phone);
            ++count;
        }
        ++i;
    }
    printf("共查询到 %d 条数据\n", count);
}

void Mod(Con* con) 数据修改

void Mod(Con* con) 
{
    assert(con);
    printf("请输入需要修改信息的联系人姓名:");
    char mod[20];
    scanf("%s", mod);
    int i = 0;
    while (i < con->size) 
    {
        if (strcmp(mod, con->data[i].name) == 0) 
        {
            printf("请更新姓名:");
            scanf("%s", con->data[i].name);
            printf("请更新号码:");
            scanf("%s", con->data[i].phone);
            return;
        }
        ++i;
    }
    printf("联系人未查询到\n");
}

void Sort(Con* con) 数据排序

int cmp_name(const void* e1, const void* e2) 
{
    return strcmp((*(Peo*)e1).name, (*(Peo*)e2).name);
}

int cmp_phone(const void* e1, const void* e2) 
{
    return strcmp((*(Peo*)e1).phone, (*(Peo*)e2).phone);
}

void Sort(Con* con) 
{
    assert(con);
    printf("请选择排序方式(1.cmp_name   2.cmp_phone):");
    int choose;
    scanf("%d", &choose);
    if (choose == 1) 
    {
        qsort(con->data, con->size, sizeof(Peo), cmp_name);
        printf("已按姓名排序成功\n");
    }
    else if (choose == 2) 
    {
        qsort(con->data, con->size, sizeof(Peo), cmp_phone);
        printf("已按号码排序成功\n");
    }
    else 
    {
        printf("输入错误,排序失败\n");
    }
}

void Print(Con* con) 打印

void Destory(Con* con) 销毁、清空

void Print(Con* con) 
{
    assert(con);
    if (Empty(con)) 
    {
        printf("通讯录为空\n");
        return;
    }
    int i = 0; 
    printf("         联系人   电话号码\n");
    while (i < con->size) 
    {
        printf("%03d: %10s %12s\n", i, con->data[i].name, con->data[i].phone);
        ++i;
    }
}

void Destory(Con* con) 
{
    assert(con);
    free(con->data);
    con->data = (Peo*)malloc(sizeof(Peo) * CAPACITY);
    if (con->data == NULL) 
    {
        perror("destory::malloc");
        exit(1);
    }
    con->size = 0;
    con->capacity = CAPACITY;
}

void Load(Con* con) 读档

void Save(Con* con) 存档

void Load(Con* con) 
{
    assert(con);
    FILE* pfRead = fopen("contact.txt", "rb");
    if (pfRead == NULL) 
        return;

    Peo tmp = { 0 };
    while (fread(&tmp, sizeof(Peo), 1, pfRead)) 
    {
        Check(con);
        con->data[con->size] = tmp;
        ++con->size;
    }
    fclose(pfRead);
    pfRead = NULL;
}

void Save(Con* con) 
{
    assert(con);
    FILE* pfWrite = fopen("contact.txt", "wb");
    if (pfWrite == NULL) 
    {
        perror("pfWrite::fopen");
        exit(1);
    }
    int i = 0;
    while (i < con->size) 
    {
        fwrite(con->data + i, sizeof(Peo), 1, pfWrite);
        ++i;
    }
    fclose(pfWrite);
    pfWrite = NULL;
}

main.c源文件

#include "contact.h"

void Menu() 
{
    printf("\n------------------------\n");
    printf("-----    0. 退出   -----\n");
    printf("-----    1. 新增   -----\n");
    printf("-----    2. 删除   -----\n");
    printf("-----    3. 查找   -----\n");
    printf("-----    4. 修改   -----\n");
    printf("-----    5. 排序   -----\n");
    printf("-----    6. 打印   -----\n");
    printf("-----    7. 清空   -----\n");
    printf("------------------------\n");
    printf("请输入选项:");
}

int main() 
{
    Con con;
    Init(&con);
    int input;
    do 
    {
        Menu();
        scanf("%d", &input);
        system("cls");
        switch (input) 
        {
        case 0:
            Save(&con);
            printf("退出通讯录\n");
            return;
        case 1:
            Add(&con);
            break;
        case 2:
            Del(&con);
            break;
        case 3:
            Find(&con);
            break;
        case 4:
            Mod(&con);
            break;
        case 5:
            Sort(&con);
            break;
        case 6:
            Print(&con);
            break;
        case 7:
            Destory(&con);
            break;
        default:
            break;
        }
    } while (input);
    return 0;
}

你可能感兴趣的:(C/C++数据结构与算法,c语言,c++,开发语言,数据结构,通讯录)