【C语言进阶】通讯录完善(动态版)

Contact.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>
#define INCREASE_MAX 2
#define INIT_MAX 3
typedef struct Contact
{
    char name[20];
    int age;
    char sex[10];
    char adress[20];
    char tele[20];
}Contact;
//typedef struct Node
//{
//    Contact people[100];
//    int size;
//}Node;

//动态通讯录
typedef struct Node
{
    Contact* people;
    int size;
    int capacity;
}Node;
//开始容量为INIT_MAX 3
//后来增加容量,每次增容INCREASE_MAX 2

void Add(Node* pc);
void Init(Node* pc);
void Show(Node* pc);
void Search(Node* pc);
void Delect(Node* pc);
void Modify(Node* pc);
void Destroy(Node* pc);
void saveContact(Node* pc);
void loadContact(Node* pc);

Contact.c

#include"Contact.h"
//动态版本
void check_capacity(Node* pc)
{
    assert(pc);
    if (pc->size == pc->capacity)
    {
        Contact* ptr = (Contact*)realloc(pc->people,sizeof(Contact)* (INCREASE_MAX+INIT_MAX));
        if (ptr == NULL)
        {
            perror("check::realloc");
            return;
        }
        pc->people = ptr;
        pc->capacity += INCREASE_MAX;
        printf("增容成功\n");
    }
}
//动态版本
void Add(Node* pc)
{
    //断言处理,判断pc是否为空
    assert(pc);
    //检查容量
    check_capacity(pc);

    //获取联系人各项信息
    printf("请输入姓名->");
    scanf("%s", pc->people[pc->size].name);
    printf("请输入年龄->");
    scanf("%d", &(pc->people[pc->size].age));
    printf("请输入性别->");
    scanf("%s", pc->people[pc->size].sex);
    printf("请输入地址->");
    scanf("%s", pc->people[pc->size].adress);
    printf("请输入电话->");
    scanf("%s", pc->people[pc->size].tele);
    //联系人数量+1
    pc->size++;
    printf("增加成功\n");
}

void Init(Node* pc)
{
    assert(pc);
    //pc->size = 0;
    //memset(pc->people, 0, sizeof(Contact) * 100);
    Contact* ptr = (Contact*)malloc(sizeof(Contact) * INIT_MAX);
    if (ptr == NULL)
    {
        perror("Add::malloc");
        return;
    }
    else
    {
        pc->people = ptr;
    }

    pc->size = 0;
    pc->capacity = INIT_MAX;
    printf("初始化成功\n");
}

void Destroy(Node* pc)
{
    //先释放结构体中指针所维护空间,再置空整个结构体
    //若先释放结构体,则结构体中指针所维护的空间无法释放,会出现问题
    free(pc->people);
    pc->people = NULL;
    pc->size = pc->capacity = 0;
    free(pc);
    pc = NULL;

}
void Show(Node* pc)
{
    //断言处理,判断pc是否为空
    assert(pc);
    int i = 0;
    //判断通讯录是否为空
    if (pc->size == 0)
    {
        printf("通讯录为空\n");
        return;
    }
    printf("%-10s%-6s%-6s%-10s%-15s\n","姓名","年龄","性别","地址","电话");
    for(i = 0; i < pc->size; i++)
    {
        printf("%-10s%-6d%-6s%-10s%-15s\n", pc->people[i].name, 
                                            pc->people[i].age, 
                                            pc->people[i].sex, 
                                            pc->people[i].adress, 
                                            pc->people[i].tele);
    }
}

int find_name(Node* pc)
{
    assert(pc);
    int i = 0;
    char name[20];
    printf("请输入要查找人的姓名->");
    scanf("%s", name);
    for (i = 0; i < pc->size; i++)
    {
        if (strcmp(pc->people[i].name, name) == 0)
            return i;
    }
    return -1;
}


void Search(Node* pc)
{
    assert(pc);
    int ret = find_name(pc);
    if (ret == -1)
        printf("没找到\n");
    else
    {
        printf("要查找人的信息->");
        printf("%-10s%-6d%-6s%-10s%-15s\n", pc->people[ret].name,
                                            pc->people[ret].age,
                                            pc->people[ret].sex,
                                            pc->people[ret].adress,
                                            pc->people[ret].tele);
    }

}

void Delect(Node* pc)
{
    assert(pc);
    int ret = find_name(pc);
    if (ret == -1)
    {
        printf("要删除的人未查找到\n");
        return;
    }
    //将要删除联系人后面的人的信息前挪
    int i = 0;
    for (i = ret; i < pc->size - 1; i++)
    {
        pc->people[i] = pc->people[i + 1];
    }
    pc->size--;
    printf("删除成功\n");
    //将最后一个人的信息填补要删除人的信息
}

void Modify(Node* pc)
{
    assert(pc);
    int ret = find_name(pc);
    if (ret == -1)
    {
        printf("要修改联系人未查找到\n");
        return;
    }
    printf("请输入姓名->");
    scanf("%s", pc->people[ret].name);
    printf("请输入年龄->");
    scanf("%d", &(pc->people[ret].age));
    printf("请输入性别->");
    scanf("%s", pc->people[ret].sex);
    printf("请输入地址->");
    scanf("%s", pc->people[ret].adress);
    printf("请输入电话->");
    scanf("%s", pc->people[ret].tele);
    pc->size++;
    printf("修改完毕\n");
}
void saveContact(Node* pc)
{
    FILE* pf = fopen("Contact.txt", "wb");
    if (pf == NULL)
    {
        perror("fopen");
        exit(-1);
    }
    //读写文件
    int i = 0;
    for (i = 0; i < pc->size; i++)
    {
        fwrite(pc->people + i, sizeof(Contact), 1, pf);
    }
    fclose(pf);
    pf = NULL;
    printf("保存成功\n");
}

void loadContact(Node* pc)
{
    FILE* pf = fopen("Contact.txt", "rb");
    if (pf == NULL)
    {
        perror("fopen");
        exit(1);
    }
    int i = 0;
    Contact tmp = { 0 };
    //要先判断容量是否充足再将读取到的数据加入通讯录中
    //因此fread第一个参数是新定义的变量而不是pc->people+i
    while(fread(&tmp,sizeof(Contact),1,pf))//未读取到数据返回0
    {
        check_capacity(pc);
        pc->people[i] = tmp;
        pc->size++;
        i++;
    }
    fclose(pf);
    pf = NULL;
}

test.c

#include"Contact.h"

void menu()
{
    printf("-----------------------------\n");
    printf("-----1.Delect  2.Search -----\n");
    printf("-----3.Modify  4.Show   -----\n");
    printf("-----5.Add     0.exit   -----\n");
    printf("-----------------------------\n");
}
enum Con
{
        Exit,
        delect,
        search,
        modify,
        show,
        add

};
int main()
{
    int input = 0;
    Node pc;
    Init(&pc);
    //加载通讯录信息
    loadContact(&pc);
    do
    {
        menu();
        printf("请输入选项->");
        scanf("%d", &input);
        switch (input)
        {
        case delect:
            Delect(&pc);
            break;
        case search:
            Search(&pc);
            break;
        case modify:
            Modify(&pc);
            break;
        case show:
            Show(&pc);
            break;
        case add:
            Add(&pc);
            break;
        case Exit:
            saveContact(&pc);
            printf("退出程序\n");
            break;
        default:
            printf("选择错误,请重新选择\n");
        }
    } while (input);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伱恏呀呀呀呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值