C语言/动态通讯录

本文使用了malloc、realloc、calloc等和内存开辟有关的函数。

 

 



前言

为了使用通讯录时,可以随时调整大小,所以使用动态开辟内存函数写通讯录,可增加联系人容量。

动态开辟函数,即在内存的栈区开辟空间,所以使用完毕后,需要释放内存空间


一、通讯录运行图

二、头文件

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#include<stdlib.h>

#define Max 10


enum function
{
    quit,//退出  默认值为0
    increase,//增加  默认值为1
    delete,//删除  默认值为2
    find,//查找   默认值为3
    revise,//修改   默认值为4
    show,//展示   默认值为5
    empty,//清空   默认值为6
    sort//排序   默认值为7
};

//创建人
typedef struct Person
{
    char name[20];//姓名
    size_t age;//年龄
    char sex[8];//性别
    char address[15];//地址
    char phone[12];//电话
}person;

//动态
//创建通讯录
typedef struct contact
{
    person *per;//指向人这个结构体类型
    size_t sz;//通讯录已有人员个数
    size_t ContactMax;//通讯录当前最大容量
}contact;

//初始化
void init_contact(contact* con);
//增容
void tune(contact* con);
//增加
void increase_contact(contact* con);
//删除
void delete_contact(contact* con);
//查找
//return -1(no) / address(yes)
int find1(const contact** con);
void find_contact(const contact* con);
//修改
void revise_contact(contact* con);
//展示
void show_contact(const contact* con);
//排序通讯录
void sort_contact(contact* con);
//销毁通讯录
void destroy_contact(contact* con);
//保存文件
void save_contact(contact* con);
//将文件信息保存到通讯录中
void load_contact(contact* con);

三、主界面

#include "contact.h"

void menu1()
{
    printf("**************************************\n");
    printf("******* Simplified address book ******\n");
    printf("*******   1> increase contact   ******\n");
    printf("*******   2> delete contact     ******\n");
    printf("*******   3> find contact       ******\n");
    printf("*******   4> revise contact     ******\n");
    printf("*******   5> Show all contacts  ******\n");
    printf("*******   6> Empty all contacts ******\n");
    printf("*******   7> Sort by name       ******\n");
    printf("*******   0> Quit Contacts      ******\n");
    printf("**************************************\n");
}

void test()
{
    //创建通讯录
    contact con;
    //初始化通讯录
    init_contact(&con);
    //将文件信息保存到通讯录中
    load_contact(&con);

    size_t choice = 0;
    do
    {
        menu1();
        printf("请输入您的选择性:");
        scanf("%u", &choice);

        switch (choice)
        {
        case increase:
            //增加
            increase_contact(&con);
            break;
        case delete:
            //删除
            delete_contact( &con );
            break;
        case find:
            //查找
            find_contact(&con);
            break;
        case revise:
            //修改
            revise_contact(&con);
            break;
        case show:
            //展示
            show_contact(&con);
            break;
        case empty:
            //清空
            init_contact(&con);
            break;
        case sort:
            //排序
            sort_contact(&con);
            break;
        case quit:
            //保存
            save_contact(&con);
            //销毁
            destroy_contact(&con);
            printf("Exiting Contacts...\n");
            break;
        default:
            printf("You entered the wrong number, please re-enter it.\n");
            break;
        }
    } while (choice);

    printf("Exited Contacts.\n");

}

int main()
{
    test();
    return 0;
}

四、通讯录功能函数

1.全代码

#include"contact.h"

void menu2()
{
    system("cls");

    printf("1> name \t 2> age\n");
    printf("3> sex \t 4> address\n");
    printf("5> phone\n");
    printf("Please select:");
}

//动态
void init_contact(contact* con)
{
    assert(con);

    // per    sz ContactMax
    con->sz = 0;

    person* p = (person*)calloc(Max, sizeof(person));
    if (p == NULL)
    {
        perror("init_contact::calloc");
        return;
    }

    con->per = p;
    con->ContactMax = Max;
}

//将文件信息保存到通讯录中
void load_contact(contact* con)
{
   //打开文件
    FILE* p = fopen("contact.txt", "rb");
    if (p == NULL)
    {
        perror("load_contact::fopen");
        return;
    }

    person tmp = { 0 };
    size_t i = 0;
    while(fread(&tmp, sizeof(person), 1, p))
    {
        //考虑增容
        tune(con);
        con->per[i] = tmp;
        con->sz++;
        i++;
    }
    //关闭文件
    fclose(p);
    p = NULL;
}


void tune(contact* con)
{
    if (con->sz == con->ContactMax)
    {
        person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));
        if (p == NULL)
        {
            perror("tune::realloc");
            return;
        }

        con->per = p;
        con->ContactMax += Max;
    }
}

//动态开辟
void increase_contact(contact* con)
{
    assert(con);
    //检测当前通讯录是否需要增容
    tune(con);

    printf("name:");
    scanf("%s", &(con->per[con->sz].name));
    printf("age:");
    scanf("%u", &(con->per[con->sz].age));
    printf("sex:");
    scanf("%s", &(con->per[con->sz].sex));
    printf("address:");
    scanf("%s", &(con->per[con->sz].address));
    printf("phone:");
    scanf("%s", &(con->per[con->sz].phone));

    (con->sz)++;
}

void delete_contact(contact* con)
{
    assert(con);

    int result = find1(&con);
            
    if (result != -1)
    {
        char true[5] = { 0 };
        printf("Are you sure you want to delete %s's information?", &con->per[result].name);
        printf("yes/no:");
        scanf("%s", true);

        if (!strcmp(true, "yes"))
        {
            if ( con->sz )
            {
                memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));
            }
            else
            {
                memset(con->per[result].name, 0, sizeof(con->per[0]));
            }
            (con->sz)--;
            printf("The deletion was successful, thanks for using!\n");          
        }
        else
        {
            printf("Delete failed, please try again!\n");
        }
    }
    else
    {
        printf("Delete failed, please try again!\n");
    }
}

int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void find_contact(const contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        printf("Found, the basic information of the contact is:");
        printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",
            con->per[result].name,
            con->per[result].age,
            con->per[result].sex,
            con->per[result].address,
            con->per[result].phone);
    }
    else
    {
        printf("Didn't find it!\n");
    }

}

void revise_contact(contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        char choice1[5] = { 0 };
        printf("Are you sure you want to revise %s's information?", con->per[result].name);
        printf("yes/no:");
        scanf("%s", choice1);

        if (!strcmp(choice1, "yes"))
        {
            menu2();
            printf("Please enter the option you want to modify:");
            int choice2 = -1;
            scanf("%d", &choice2);

            char sample1[30] = { 0 };
            size_t sample2 = 0;

            printf("请输入:");
            switch ( choice2 )
            {
            case 1:
            case 3:
            case 4:
            case 5:
                scanf("%s", sample1);
                break;
            case 2:
                scanf("%d", sample2);
                break;
            }

            switch (choice2)
            {
            case 1:
                memmove(con->per[result].name, sample1, sizeof(sample1));
                break;
            case 3:
                memmove(con->per[result].sex, sample1, sizeof(sample1));
                break;
            case 4:
                memmove(con->per[result].address, sample1, sizeof(sample1));
                break;
            case 5:
                memmove(con->per[result].phone, sample1, sizeof(sample1));
                break;
            case 2:
                con->per[result].age = sample2;
                break;
            }

            printf("修改成功,感谢使用!!!\n");
        }
        else
        {
            printf("修改失败,请再次尝试!!!\n");
        }
    }
    else
    {
        printf("修改失败,请再次尝试!!!\n");
    }
}

void show_contact(const contact* con)
{
    assert(con);

    printf("\n\n================================================\n");
    printf("================================================\n\n");

    if ( con->sz )
    {
        size_t i = 0;
        for (; i < (con->sz); i++)
        {
            printf("name:%-20s\tage:%-4d\tsex:%-8s\taddress:%-15s\tphone:%-12s\n",
                con->per[i].name, con->per[i].age, con->per[i].sex,
                con->per[i].address, con->per[i].phone);
        }
        printf("\n\n");
    }
    else
    {
        printf("There is no contact information in the address book!\n");
    }
}

int cmp_char(const void* str1, const void* str2)
{
    return strcmp(((person*)str1)->name, ((person*)str2)->name);
}

void sort_contact(contact* con)
{
    qsort(con -> per[0].name, con -> sz, sizeof(con -> per[0]), cmp_char);
}

void destroy_contact(contact* con)
{
    free(con->per);
    con->per = NULL;
    con->ContactMax = 0;
    con->sz = 0;
    con = NULL;
}

void save_contact(contact* con)
{
    //写文件
    FILE* p = fopen("contact.txt", "wb");
    if (p == NULL)
    {
        perror("save_contact::fopen");
        return;
    }

    int i = 0;
    for (i = 0; i < con->sz; i++)
    {
        fwrite(con->per + i, sizeof(person), 1, p);
    }
    //关闭文件
    fclose(p);
    p = NULL;
    printf("保存成功\n");
}

2.增加联系人

使用realloc()调整通讯录大小。

联系人信息图为:

void tune(contact* con)
{
    if (con->sz == con->ContactMax)
    {
        person *p = (person *)realloc(con->per, (con->ContactMax + Max) * sizeof(person));
        if (p == NULL)
        {
            perror("tune::realloc");
            return;
        }

        con->per = p;
        con->ContactMax += Max;
    }
}

//动态开辟
void increase_contact(contact* con)
{
    assert(con);
    //检测当前通讯录是否需要增容
    tune(con);

    printf("name:");
    scanf("%s", &(con->per[con->sz].name));
    printf("age:");
    scanf("%u", &(con->per[con->sz].age));
    printf("sex:");
    scanf("%s", &(con->per[con->sz].sex));
    printf("address:");
    scanf("%s", &(con->per[con->sz].address));
    printf("phone:");
    scanf("%s", &(con->per[con->sz].phone));

    (con->sz)++;
}

3.删除联系人

通过联系人的姓名来查找需要删除的联系人,找到之后确认删除该联系人。

例如:

 

int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}


void delete_contact(contact* con)
{
    assert(con);

    int result = find1(&con);
            
    if (result != -1)
    {
        char true[5] = { 0 };
        printf("Are you sure you want to delete %s's information?", &con->per[result].name);
        printf("yes/no:");
        scanf("%s", true);

        if (!strcmp(true, "yes"))
        {
            if ( con->sz )
            {
                memmove(con->per[result].name, con->per[(con->sz) - 1].name, sizeof(con->per[0]));
            }
            else
            {
                memset(con->per[result].name, 0, sizeof(con->per[0]));
            }
            (con->sz)--;
            printf("The deletion was successful, thanks for using!\n");          
        }
        else
        {
            printf("Delete failed, please try again!\n");
        }
    }
    else
    {
        printf("Delete failed, please try again!\n");
    }
}

4.查找联系人

通过联系人姓名查找联系人。


int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void find_contact(const contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        printf("Found, the basic information of the contact is:");
        printf("name:%-20s\tage:%-4d\tsex:%-5s\taddress:%-30s\tphone:%-12s\n",
            con->per[result].name,
            con->per[result].age,
            con->per[result].sex,
            con->per[result].address,
            con->per[result].phone);
    }
    else
    {
        printf("Didn't find it!\n");
    }

}

5.修改联系人

先查找,再修改。

可以修改联系人的任一信息。


int find1(const contact** con)
{
    assert(*con);

    size_t i = 0;
    char sample1[20] = { 0 };

    printf("请输入你要查找的名字:");
    scanf("%s", sample1);

    while (i < (*con)->sz)
    {
        if (!strcmp(sample1, (*con)->per[i].name))
        {
            return i;
        }
        else
        {
            i++;
        }
    }

    return -1;
}

void revise_contact(contact* con)
{
    assert(con);

    int result = find1(&con);

    if (result != -1)
    {
        char choice1[5] = { 0 };
        printf("Are you sure you want to revise %s's information?", con->per[result].name);
        printf("yes/no:");
        scanf("%s", choice1);

        if (!strcmp(choice1, "yes"))
        {
            menu2();
            printf("Please enter the option you want to modify:");
            int choice2 = -1;
            scanf("%d", &choice2);

            char sample1[30] = { 0 };
            size_t sample2 = 0;

            printf("请输入:");
            switch ( choice2 )
            {
            case 1:
            case 3:
            case 4:
            case 5:
                scanf("%s", sample1);
                break;
            case 2:
                scanf("%d", sample2);
                break;
            }

            switch (choice2)
            {
            case 1:
                memmove(con->per[result].name, sample1, sizeof(sample1));
                break;
            case 3:
                memmove(con->per[result].sex, sample1, sizeof(sample1));
                break;
            case 4:
                memmove(con->per[result].address, sample1, sizeof(sample1));
                break;
            case 5:
                memmove(con->per[result].phone, sample1, sizeof(sample1));
                break;
            case 2:
                con->per[result].age = sample2;
                break;
            }

            printf("修改成功,感谢使用!!!\n");
        }
        else
        {
            printf("修改失败,请再次尝试!!!\n");
        }
    }
    else
    {
        printf("修改失败,请再次尝试!!!\n");
    }
}

6.展示联系人

展示所有联系人及其所有信息。

void show_contact(const contact* con)
{
    assert(con);

    printf("\n\n================================================\n");
    printf("================================================\n\n");

    if ( con->sz )
    {
        size_t i = 0;
        for (; i < (con->sz); i++)
        {
            printf("name:%-20s\tage:%-4d\tsex:%-8s\taddress:%-15s\tphone:%-12s\n",
                con->per[i].name, con->per[i].age, con->per[i].sex,
                con->per[i].address, con->per[i].phone);
        }
        printf("\n\n");
    }
    else
    {
        printf("There is no contact information in the address book!\n");
    }
}

7.清空联系人

又名初始化通讯录。

重新向内存申请一片空间,存储联系人信息。

void init_contact(contact* con)
{
    assert(con);

    // per    sz ContactMax
    con->sz = 0;

    person* p = (person*)calloc(Max, sizeof(person));
    if (p == NULL)
    {
        perror("init_contact::calloc");
        return;
    }

    con->per = p;
    con->ContactMax = Max;
}

8.退出通讯录

通过free()释放内存栈区的空间,避免内存泄露。

void destroy_contact(contact* con)
{
    free(con->per);
    con->per = NULL;
    con->ContactMax = 0;
    con->sz = 0;
    con = NULL;
}

总结

在使用完内存函数之后,一定一定要记得释放空间哦~

上述代码展示就是整个动态通讯录的全部啦,如果你有兴趣想要了解,可以通过C_Ccpp/C_study/contact at main · Yjun6/C_Ccpp (github.com)找到它们。

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
ava实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),可运行高分资源 Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现的毕业设计&&课程设计(包含运行文档+数据库+前后端代码),Java实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Y君的进化史

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

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

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

打赏作者

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

抵扣说明:

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

余额充值