前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言/动态通讯录

C语言/动态通讯录

作者头像
用户10788736
发布2023-10-16 08:29:50
2010
发布2023-10-16 08:29:50
举报
文章被收录于专栏:CSDN搬移文章

前言

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

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

一、通讯录运行图

二、头文件

代码语言:javascript
复制
#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);

三、主界面

代码语言:javascript
复制
#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.全代码

代码语言:javascript
复制
#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()调整通讯录大小。

联系人信息图为:

代码语言:javascript
复制
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.删除联系人

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

例如:

代码语言:javascript
复制
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.查找联系人

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

代码语言:javascript
复制
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.修改联系人

先查找,再修改。

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

代码语言:javascript
复制
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.展示联系人

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

代码语言:javascript
复制
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.清空联系人

又名初始化通讯录。

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

代码语言:javascript
复制
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()释放内存栈区的空间,避免内存泄露。

代码语言:javascript
复制
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)找到它们。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-03-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 二、头文件
  • 三、主界面
  • 四、通讯录功能函数
    • 1.全代码
      • 2.增加联系人
        • 3.删除联系人
          • 4.查找联系人
            • 5.修改联系人
              • 6.展示联系人
                • 7.清空联系人
                  • 8.退出通讯录
                  • 总结
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档