C语言实现简单的通讯录管理系统

 更新时间:2022年06月15日 10:00:42   作者:今天也要写bug、  
这篇文章主要为大家详细介绍了C语言实现通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言实现通讯录管理系统的具体代码,供大家参考,具体内容如下

要实现一个通讯录管理系统,需要用到结构体、指针、文件操作、动态管理等内容。

效果展示:

实现思路

通讯录中的联系人包括姓名、年龄、性别、电话、住址,因此可以定义一个结构体PeoInfo来存储这些信息。

同时,由于通讯录需要记录当前的大小,以此来方便我们对通讯录realloc进行扩容,所以需要定义通讯录结构体Contact来保存这些信息,其中该结构体中可以嵌套一个PeoInfo类型的指针。

当定义完结构体以后,就可以对定义的结构体进行增删查改,其中可以先使用malloc对通讯录结构体进行初始化,然后再完成添加、删除、查找、修改、保存、排序、清空等一系列函数。

在保存时,需要用到文件指针将数据保存到文件中,因此在一开始当前目录下需要一个相应的文件。
同时在初始化时,也要将文件中的数据读取到我们的结构体指针指向的内容中。
在这里使用contact.txt文件来保存信息:

为了方便,我们将函数声明,函数实现,以及游戏的实现放到三个不同文件里:

contact.h内容

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>

#define MAX_NAME 10//名字的大小
#define MAX_SEX 5//性别大小
#define MAX_TELE 15//电话大小
#define MAX_ADDR 30//地址大小
#define DEFAULT_SZ 3 //通讯录默认的大小

enum Option
{
    EXIT,
    ADD,
    DEL,
    SEARCH,
    MODIFY,
    SHOW,
    SORT,
    SAVE,
    CLEAR
};
struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char tele[MAX_TELE];
    char addr[MAX_ADDR];
};

//通讯录类型
struct Contact
{
    struct PeoInfo* data;//存放信息
    int size;//记录当前已经有的元素个数
    int capacity;//当前通讯录的最大容量
};

//初始化通讯录
void InitContact(struct Contact* ps);

//增加通讯录内容
void AddContact(struct Contact* ps);

//打印通讯录信息
void ShowContact(const struct Contact* ps);

//删除通讯录信息
void DelContact(struct Contact* ps);

//查找通讯录信息
void SearchContact(const struct Contact* ps);

//修改指定联系人
void ModifyContact(struct Contact* ps);

//按姓名排序
void SortContact(struct Contact* ps);

//释放动态开辟的内存
void DestroyContact(struct Contact* ps);

//保存通讯录
void SaveContact(struct Contact* ps);

//加载文件中的信息到通讯录
void LoadContact(struct Contact* ps);

//清空通讯录
void ClearContact(struct Contact* ps);

这个文件中主要包括结构体的创建,以及各种函数的声明。

contact.c内容

#include"contact.h"

void InitContact(struct Contact* ps)
{
    ps ->data =(struct PeoInfo*) malloc(DEFAULT_SZ * sizeof(struct PeoInfo));
    if (ps->data == NULL)
    {
        printf("空间开辟失败");
        return;
    }
    ps->size = 0;
    ps->capacity = DEFAULT_SZ;
    //把文件中存放的信息加载到通讯录中
    LoadContact(ps);
}
void CheckCapacity(struct Contact* ps)
{
    if (ps->size == ps->capacity)
    {
        struct PeoInfo* ptr = (struct PeoInfo*)realloc(ps->data, (ps->capacity + 5) * sizeof(struct PeoInfo));
        if (ptr != NULL)
        {
            ps->data = ptr;
            ps->capacity += 5;
        }
    }
}
void LoadContact(struct Contact* ps)
{
    struct PeoInfo tmp = { 0 };
    FILE* pfRead = fopen("contact.txt", "rb");
    if (pfRead == NULL)
    {
        printf("文件不存在:%s\n", strerror(errno));
        return;
    }
    //读取文件
    while (fread(&tmp, sizeof(struct PeoInfo), 1, pfRead))
    {
        CheckCapacity(ps);
        ps->data[ps->size] = tmp;
        ps->size++;
    }
    fclose(pfRead);
    pfRead = NULL;
}


void AddContact(struct Contact* ps)
{
    //检测当前通讯录的容量,如果满了则增容
    CheckCapacity(ps);
    printf("请输入名字->");
    scanf("%s", ps->data[ps->size].name);
    printf("请输入年龄->");
    scanf("%d", &(ps->data[ps->size].age));
    printf("请输入性别->");
    scanf("%s", ps->data[ps->size].sex);
    printf("请输入电话->");
    scanf("%s", ps->data[ps->size].tele);
    printf("请输入地址->");
    scanf("%s", ps->data[ps->size].addr);
    
    ps->size++;
    printf("添加成功\n");
    
}

void ShowContact(const struct Contact* ps)
{
    if (ps->size == 0)
    {
        printf("通讯录为空\n");

    }
    else
    {
        int i = 0;
        printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");
        {
            for (i = 0; i < ps->size; i++)//打印每个通讯录元素
            {
                printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\n", 
                    ps->data[i].name, ps->data[i].age, ps->data[i].sex, 
                    ps->data[i].tele, ps->data[i].addr);
            }
        }
    }
}
//查找联系人位置
int FindByName(const struct Contact* ps, char name[MAX_NAME])
{
    //查找要删除人的位置
    int i = 0;
    for (i = 0; i < ps->size; i++)
    {
        if (0 == strcmp(ps->data[i].name, name))
        {
            return i;//找到返回下标
        }
    }
    return -1;//找不到返回-1
}

void DelContact(struct Contact* ps)
{
    char name[MAX_NAME];
    printf("请输入要删除人的名字:->");
    scanf("%s", name);
    //查找要删除人的位置
    int pos=FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1
    
    if (pos==-1)
    {
        printf("联系人不存在\n");
    }
    else
    {
        //删除
        int j = 0;
        for (j = pos; j < ps->size-1; j++)
        {
            ps->data[j] = ps->data[j + 1];
        }
        ps->size--;
        printf("删除成功\n");
    }

}

void SearchContact(const struct Contact* ps)
{
    char name[MAX_NAME];
    printf("请输入要查找人的名字:->");
    scanf("%s", name);
    int pos = FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1
    if (pos == -1)
    {
        printf("联系人不存在\n");
    }
    else
    {
        printf("%-10s\t%-4s\t%-5s\t%-12s\t%-20s\n", "名字", "年龄", "性别", "电话", "地址");        
        printf("%-10s\t%-4d\t%-5s\t%-12s\t%-20s\n",
         ps->data[pos].name, ps->data[pos].age, ps->data[pos].sex,
         ps->data[pos].tele, ps->data[pos].addr);
            
    }        
}

void ModifyContact(struct Contact* ps)
{
    char name[MAX_NAME];
    printf("请输入要修改人的名字:->");
    scanf("%s", name);
    int pos = FindByName(ps, name);//找到返回名字所在的下标,找不到返回-1
    if (pos == -1)
    {
        printf("联系人不存在\n");
    }
    else
    {
        printf("请输入名字->");
        scanf("%s", ps->data[pos].name);
        printf("请输入年龄->");
        scanf("%d", &(ps->data[pos].age));
        printf("请输入性别->");
        scanf("%s", ps->data[pos].sex);
        printf("请输入电话->");
        scanf("%s", ps->data[pos].tele);
        printf("请输入地址->");
        scanf("%s", ps->data[pos].addr);

        printf("修改完成\n");
    }
}

void SortContact(struct Contact* ps)
{
    for (int i = 0; i < ps->size - 1; ++i)
    {
        for (int j = 0; j < ps->size - i - 1; ++j)
        {
            if (strcmp(ps->data[j].name, ps->data[j + 1].name) > 0)
            {
                struct PeoInfo tmp = ps->data[j];
                ps->data[j] = ps->data[j + 1];
                ps->data[j + 1] = tmp;
            }
        }
    }
    printf("按姓名排序成功\n");
}

//释放动态开辟的空间
void DestroyContact(struct Contact* ps)
{
    free(ps->data);
    ps->data=NULL;
}


void SaveContact(struct Contact* ps)
{
    FILE* pfWrite = fopen("contact.txt", "wb");
    if (pfWrite == NULL)
    {
        printf("%s\n", strerror(errno));
        return;
    }
    //将通讯录的信息写入文件
    int i = 0;
    for (i = 0; i < ps->size; i++)
    {
        fwrite(&(ps->data[i]), sizeof(struct PeoInfo), 1, pfWrite);
    }
    printf("保存成功\n");
    fclose(pfWrite);
    pfWrite = NULL;
}

void ClearContact(struct Contact* ps)
{
    printf("确定要清空通讯录吗?<Y/N> :>");
    char ch;
    getchar();//清空缓存区里面的\n
    scanf("%c", &ch);
    if (ch == 'Y' || ch == 'y')
    {
        ps->size = 0;
        memset(ps->data, 0, sizeof(ps->data));
        printf("清空成功\n");
    }
    else
    {
        printf("取消清空\n");
    }
    
}

在这个文件中我们将声明的函数进行了定义,用到的方法都比较简单。

test.c内容

#include"contact.h"
void menu()
{
    printf("**************************************************\n");
    printf("****1.添加联系人        2.删除联系人**************\n");
    printf("****3.查找联系人        4.修改联系人*************\n");
    printf("****5.展示所有联系人    6.按姓名排序联系人********\n");
    printf("****7.保存通讯录        8.清空通讯录*************\n");
    printf("**************0.退出通讯录************************\n");
    printf("**************************************************\n");
}


int main()
{
    int input = 0;
    //创建通讯录
    int size = 0;
    struct Contact con;//con是通讯录
    //初始化通讯录
    InitContact(&con);

    do
    {
        menu();
        printf("请选择->");
        scanf("%d", &input);
        switch (input)
        {
        case ADD:
            AddContact(&con);
            system("pause");
            system("cls");
            break;
        case DEL:
            DelContact(&con);
            system("pause");
            system("cls");
            break;
        case SEARCH:
            SearchContact(&con);
            system("pause");
            system("cls");
            break;
        case MODIFY:
            ModifyContact(&con);
            system("pause");
            system("cls");
            break;
        case SHOW:
            ShowContact(&con);
            system("pause");
            system("cls");
            break;
        case SORT:
            SortContact(&con);
            system("pause");
            system("cls");
            break;
        case SAVE:
            SaveContact(&con);
            system("pause");
            system("cls");
            break;
        case CLEAR:
            ClearContact(&con);
            system("pause");
            system("cls");
            break;
        case EXIT:
            SaveContact(&con);
            //释放动态开辟的内存
            DestroyContact(&con);
            break;
        default:
            printf("选择错误\n");
            break;
        }
    } while (input);
}

在这个文件中将对菜单进行打印,同时进行函数的调用。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C/C++ pthread线程库使用示例详解

    C/C++ pthread线程库使用示例详解

    这篇文章主要介绍了C/C++ pthread线程库使用示例详解,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • 探讨C++中数组名与指针的用法比较分析

    探讨C++中数组名与指针的用法比较分析

    本篇文章是对C++中数组名与指针用法的比较进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C++程序函数的重载和函数模板示例代码

    C++程序函数的重载和函数模板示例代码

    C++允许在同一作用域中用同一函数名定义多个函数,这些函数的参数个数和参数类型不相同,这些同名的函数用来实现不同的功能,这就是函数的重载,这篇文章主要介绍了C++程序函数的重载和函数模板,需要的朋友可以参考下
    2024-03-03
  • C语言实现页面置换算法

    C语言实现页面置换算法

    这篇文章主要为大家详细介绍了C语言实现页面置换算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • C++实现翻转单词顺序

    C++实现翻转单词顺序

    这篇文章给大家汇总介绍了C++实现翻转单词顺序的三种方法,都非常的简单,需要的朋友可以参考下
    2016-07-07
  • 判断给定的图是不是有向无环图实例代码

    判断给定的图是不是有向无环图实例代码

    判断给定的图是不是是有向无环图,方法是应用拓扑排序,代码如下
    2013-05-05
  • C语言也有封装,继承和多态你知道吗

    C语言也有封装,继承和多态你知道吗

    这篇文章主要为大家详细介绍了C语言封装,继承,多态,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-03-03
  • C语言详解冒泡排序实现

    C语言详解冒泡排序实现

    冒泡排序是一种简单的排序算法,它也是一种稳定排序算法。其实现原理是重复扫描待排序序列,并比较每一对相邻的元素,当该对元素顺序不正确时进行交换。一直重复这个过程,直到没有任何两个相邻元素可以交换,就表明完成了排序
    2022-04-04
  • 实例讲解C++ 命名空间

    实例讲解C++ 命名空间

    这篇文章主要介绍了C++ 命名空间的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下
    2020-06-06
  • C语言中的运算符优先级和结合性一览表

    C语言中的运算符优先级和结合性一览表

    这篇文章主要介绍了C语言中的运算符优先级和结合性一览表,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02

最新评论