C语言实现通信录

//需要创建三个文档,两个源文件,一个头文件

//第一个测试源文件为

#include "contast.h"

void menu()
{
    printf("************************************\n");
    printf("****** 1.ADD         2.DEL *********\n");
    printf("****** 3.RESEARCH    4.MODIFY ******\n");
    printf("****** 5.SHOW        0.EXIT  *******\n");
    printf("************************************\n");
}
void Init_Contact(struct contact* p)//初始化通信录里的信息
{
    p->size=0;
    p->capacity=3;
    p->data=(struct people*)malloc(p->capacity*(sizeof(struct people)));
    Load_catact(p);//进行将之前通信录数据的导入
}
int main()
{
    int input=0;
    struct contact p1;
    Init_Contact(&p1);
    do
    {
        menu();        
        printf("请输入你的选择:");
        scanf("%d",&input);
        switch(input)
        {
        case ADD://ADD DEL等利用枚举可以增加文档的可读性
            ADD_contact(&p1);
            break;
        case DEL:
            DEL_contact(&p1);
            break;
        case RESEARCH:
            RESEARCH_contact(&p1);
            break;
        case MODIFY:
            MODIFY_contact(&p1);
            break;
        case SHOW:
            SHOW_contact(&p1);
            break;
        case EXIT:

            Save_catact(&p1);//保存通信录数据
            free(p1.data);
            p1.data=NULL;
            break;
        default:
            printf("输入错误请重新输入\n");
        }
    }
    while(input);
    return 0;
}

//第二个源文件为contact.c

#include "contast.h"

static int Find_name(struct contact* p,char* name)//设置为静态的原因是让他只能再contact.c文件内使用
{
    int i=0;
    for(i=0;i<p->size;i++)//最多查找size次
    {
        if(0==strcmp(p->data[i].name,name))//比较两个字符串是否相同,相同返回i
            return i;
    }
    return -1;//没查找到相同的字符串直接返回-1
}

void Just_capacity(struct contact* p)//判断是否需要扩容
{
    if(p->size==p->capacity)
    {
        struct people* ret=(struct people*)realloc(p->data,(p->capacity+2)*sizeof(struct people));
        if(ret!=NULL)
        {    
            p->data=ret;
            p->capacity+=2;
            printf("扩容成功\n");
        }
        else
        printf("%s",strerror(errno));
    }
}
void ADD_contact(struct contact* p)//添加联系人
{
    Just_capacity(p);

    printf("姓名:");
    scanf("%s",p->data[p->size].name);
    printf("电话:");
    scanf("%s",p->data[p->size].number);
    printf("地址:");
    scanf("%s",p->data[p->size].address);
    printf("性别:");
    scanf("%s",p->data[p->size].sex);
    printf("年龄:");
    scanf("%d",&(p->data[p->size].age));//再添加age的时候需要注意的是需要取地址,因为age是一个int类型变量,其他为字符类型
    p->size++;//size是计算通信率中人的个数
    printf("添加成功\n");
}
void SHOW_contact(struct contact* p)//显示通信录
{
    int i=0;
    printf("%-10s %-11s %-10s %-5s %s\n","名字","电话","地址","性别","年龄");//负号表示左对齐,数字表示空多少个格
    for(i=0;i<p->size;i++)
    {
        printf("%-10s %-11s %-10s %-5s %-4d\n",p->data[i].name,p->data[i].number,p->data[i].address,p->data[i].sex,p->data[i].age);
    }
}

void DEL_contact(struct contact* p)
{
    char name[NAME_MAX]={0};
    int j=0;
    printf("请输入你所要删除的名字:");
    scanf("%s",name);
    j=Find_name(p,name);//返回的值,为查找到的第一个名字所在数组的位置
    if(Find_name(p,name)==-1)
        printf("没有找到你所输入的联系人:\n");
    else
    {
        for(j=Find_name(p,name);j<p->size-1;j++)
        {
            p->data[j]=p->data[j+1];//将所删除的位置进行覆盖(将后面的数挪到前面来)
        }
        p->size--;//由于删除了一个人,则通信录中人的个数减一
    }
}
void RESEARCH_contact(struct contact* p)//查找通信录中的某个人
{
    char name[NAME_MAX]={0};
    int i=0;
    printf("请输入你所要查找的名字:");
    scanf("%s",name);
    i=Find_name(p,name);
    if(i==-1)
        printf("没有找到你所输入的联系人:\n");
    else
    {
        printf("%-10s %-11s %-10s %-5s %s\n","名字","电话","地址","性别","年龄");
        printf("%-10s %-11s %-10s %-5s %-4d\n",p->data[i].name,p->data[i].number,p->data[i].address,p->data[i].sex,p->data[i].age);
    }
}
void MODIFY_contact(struct contact* p)//修改通信录中的某个人的信息
{
    char name[NAME_MAX]={0};
    int i=0;
    printf("请输入你所要修改的名字:");
    scanf("%s",name);
    i=Find_name(p,name);//先查找你所修改的那个人所在位置
    if(i==-1)
        printf("没有找到你所输入的联系人:\n");
    else
    {
        printf("请输入你要修改的信息:\n");
        printf("姓名:");
        scanf("%s",p->data[i].name);
        printf("电话:");
        scanf("%s",p->data[i].number);
        printf("地址:");
        scanf("%s",p->data[i].address);
        printf("性别:");
        scanf("%s",p->data[i].sex);
        printf("年龄:");
        scanf("%d",&(p->data[i].age));
        printf("修改成功\n");
    }
}

void Save_catact(struct contact* p)
{
    int i=0;
    FILE* pf=fopen("text.txt","wb");//将通信录以2进制的形式进行写入文件
    if(pf==NULL)
    {
        printf("Save:%s",strerror(errno));
    }
    for(i=0;i<p->size;i++)
    {
        fwrite(p->data,sizeof(struct people),1,pf);//进行写入size次
    }
    fclose(pf);//释放动态内存,每当用到动态内存时,在用完之后都需要释放
    pf=NULL;
}
void Load_catact(struct contact* p)//将原本的存储的信息进行读取,以便于这次存入之后下一次就可以直接看到
{
    struct people temp={0};
    FILE* pf=fopen("text.txt","rb");//打开文件以2进制的形式读取
    if(pf==NULL)
    {
        printf("Load:%s",strerror(errno));
    }
    while(fread(&temp,sizeof(struct people),1,pf))//fread函数可以读取文件文件的数据,&temp是读取后暂时存放的位置,sizeof(struct people)是每一次读取的大小,1是读取对象的个数,pf是输入流,read函数的返回值如果是未读取到则返回0可跳出循环
    {
        Just_capacity(p);//判断是否需要扩容
        p->data[p->size]=temp;//将temp读取到的数据转存到p->data[p->size]内
        p->size++;//每次读取后size的内容加一
    }
    fclose(pf);//释放动态内存,每当用到动态内存时,在用完之后都需要释放
    pf=NULL;//释放完之后并不会将pf的内容置为空指针需要手动置为空指针,防止非法访问
}

//头文件为contact.h

#include <stdio.h>
#include <string.h>
#define NAME_MAX 10
#define NUMBER_MAX 11
#define ADDRESS_MAX 10
#define SEXE_MAX 5
enum option
{
    EXIT,
    ADD,
    DEL,
    RESEARCH,
    MODIFY,
    SHOW,
};

struct people
{
    char name[NAME_MAX];
    char number[NUMBER_MAX];
    char address[ADDRESS_MAX];
    char sex[SEXE_MAX];
    int age;
};

struct contact
{
    struct people* data;//利用了结构体的嵌套
    int size;
};

void ADD_contact(struct contact* p);
void SHOW_contact(struct contact* p);
void DEL_contact(struct contact* p);
void RESEARCH_contact(struct contact* p);
void MODIFY_contact(struct contact* p);

void Just_capacity(struct contact* p);
void Save_catact(struct contact* p);
void Load_catact(struct contact* p);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值