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

如何来实现通信录呢?

人的信息包括:名字+年龄+性别+电话+地址,等来表示

想要实现的功能:

1、默认存放100个人的信息

2、增加联系人信息

3、删除指定联系人信息

4、查找联系人信息

5、修改联系人信息

6、对联系人信息排序

7、显示联系人

想要实现通讯录管理系统 需要多个文件:

test.c                测试功能

contact.c          通讯录相关的实现

contact.h          通讯录相关的声明

接下来我们就来依次看这几个文件,首先对 test.c 文件搭建基本框架 :

#include"contact.h"

void menu()
{
	printf("**************************************************\n");
	printf("--------------欢迎进入通讯录管理系统--------------\n");
	printf("**************************************************\n");
	printf("*************    1.增加联系人信息   **************\n");
	printf("*************    2.删除联系人信息   **************\n");
	printf("*************    3.查找联系人信息   **************\n");
	printf("*************    4.修改联系人信息   **************\n");
	printf("*************    5.排序联系人信息   **************\n");
	printf("*************    6.显示联系人信息   **************\n");
	printf("*************     0.退出管理系统    **************\n");
	printf("**************************************************\n");
}
int main()
{
	int input = 0;
    //PeoInfo data[100];//存放100个人的信息,但是当我们进行增删查改一系列操作时,data里的实际有效元素,信息人的个数不断发生变化,需要变量记录一下
//int count = 0;//用来记录通讯录里面联系人有多少,可以封装成一个结构体
    Contact con;//通讯录
    //初始化通讯录,可以用大括号初始化,之所以写函数来初始化,是为了让代码封装位模块的形式,另一方面是因为初始化的内容有些不能通过大括号来初始化
    InintContact(&con);//传址调用,1、节省空间,提高效率2、函数内部可以直接操作con的内容
	do
	{
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 6:
			break;
		case 0:
			printf("退出管理系统\n");
			break;
		default:
			printf("选择错误请重新选择\n");
		}
	} while (input);
	return 0;
}

接下来我们在 Contact.h 文件中进行类型的声明:

#include<stdio.h>
#include<string.h>
//类型的声明
typedef struct PeoInfo
{
	char name[20];
	int age;
	char sex[10];
	char tel[12];
	char addr[30];
}PeoInfo;
typedef struct Contact
{
	PeoInfo data[100];
	int count;
}Contact;

函数的实现在 Contact.c 文件中实现,首先我们应该对通讯录初始化,再分别实现各个函数的功能

#include"contact.h"
void InitContact(Contact* pc)
{
	pc->count = 0;
	memset(pc->data, 0, sizeof(pc->data));//memset内存设置函数:将指向内存块的字节设置为指定值,当然也可以通过循环来解决但较为麻烦
}

 我们来看第一个函数如何实现(增加联系人信息):

#include"Contact.h"
void AddContact(Contact* pc)
{
	if (pc->data == MAX)
	{
		printf("通讯录已满,无法进行添加操作\n");
		return;
	}
	//未满,进行添加操作
	printf("请输入名字:>");//如果data里面没有数据,count就为0,可以作为下标,count为1时说明里面有1个数据,下标为1
	scanf("%s", pc->data[pc->count].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[pc->count].age));
	printf("请输入性别:>");
	scanf("%s", pc->data[pc->count].sex);
	printf("请输入电话:>");
	scanf("%s", pc->data[pc->count].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->count].addr);
	pc->count++;
	printf("增加成功\n");
}
void ShowContact(const Contact* pc)
{
	int i = 0;
	printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");//\t表示的是水平制表符的意思,为了美观空出来,-表示左对齐的意思
	for (i = 0; i < pc->count; i++)
	{
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tel, pc->data[i].addr);
	}
}

注意: 在这里我们之所以写了显示联系人信息的函数是因为,我们可以在增加联系人信息后,把联系人信息打印出来,以此来判断增加信息是否有误

然后我们再来实现删除联系人信息的函数操作:

 static int FindbyName(Contact* pc,char name[])//只能在这个Contact.c文件中使用
{
	int i = 0;
	for (i = 0; i < pc->count; i++)
	{
		if (strcmp(pc->data[i].name,name)==0)
		{
			return i;
		}
	}
	return -1;
}
void DelContact(Contact* pc)
{
	int i = 0;
	//我们可以按照名字来删除,当然也可以按照其他的来删除
	char name[MAX_NAME] = { 0 };//删除联系人的前提是数据不为空,所以我们应该先判断一下
	if (pc->count == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入将要删除联系人姓名:>");
	scanf("%s", name);
	//删除联系人分两步,先查找是否存在该联系人,若存在才可删除
	//1、查找
	int ret=FindbyName(pc, name);//因为查找联系人、删除、修改、都要查找,所以封装一个函数,若找到返回下标,反之返回-1
	if (ret == -1)
	{
		printf("该联系人不存在\n");
		return;
	}
	//2、删除,可以把后面的元素往前覆盖即可
	for (i = ret; i < pc->count-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->count--;
	printf("删除成功\n");
	//也可以用memove来删除:memmove(&(pc->data[ret]), &(pc->data[ret + 1]), (pc->count - ret) * (sizeof(Contact)));但必须保证通讯录中联系人信息是连续的
}

Contact.c 中实现查找联系人的信息:

void SearchContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("请输入将要查找联系人姓名:>");
	scanf("%s", name);
	int ret = FindbyName(pc, name);
	if (ret == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	else
	{
		printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
		printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tel, pc->data[ret].addr);
	}
}

修改联系人信息:

void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("请输入将要修改联系人姓名:>");
	scanf("%s", name);
	int ret = FindbyName(pc, name);
	if (ret == -1)
	{
		char name[MAX_NAME] = { 0 };
		printf("该联系人不存在\n");
		return;
	}
	printf("请输入名字:>");
	scanf("%s", pc->data[ret].name);
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[ret].age));
	printf("请输入性别:>");
	scanf("%s", pc->data[ret].sex);
	printf("请输入电话:>");
	scanf("%s", pc->data[ret].tel);
	printf("请输入地址:>");
	scanf("%s", pc->data[ret].addr);
	printf("修改成功\n");
}

对联系人信息排序:

int cmp_by_name(const char* e1, const char* e2)
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
	//假如按照名字排序,快排
	qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
	printf("排序成功\n");
}

现在把代码总结到一起的话:

//contact.h文件

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 10
#define MAX_TEL 12
#define MAX_ADDR 30
//类型的声明
typedef struct PeoInfo
{
    char name[MAX_NAME];
    int age;
    char sex[MAX_SEX];
    char tel[MAX_TEL];
    char addr[MAX_ADDR];
}PeoInfo;
typedef struct Contact
{
    PeoInfo data[MAX];
    int count;
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加联系人信息
void AddContact(Contact* pc);
//显示联系人信息
void ShowContact(const Contact* pc);
//删除联系人信息
void DelContact(Contact* pc);
//查找联系人信息
void SearchContact(Contact* pc);
//修改联系人信息
void ModifyContact(Contact* pc);
//排序联系人信息
void SortContact(Contact* pc); 

//test.c文件

#include"contact.h"

void menu()
{
    printf("**************************************************\n");
    printf("--------------欢迎进入通讯录管理系统--------------\n");
    printf("**************************************************\n");
    printf("*************    1.增加联系人信息   **************\n");
    printf("*************    2.删除联系人信息   **************\n");
    printf("*************    3.查找联系人信息   **************\n");
    printf("*************    4.修改联系人信息   **************\n");
    printf("*************    5.排序联系人信息   **************\n");
    printf("*************    6.显示联系人信息   **************\n");
    printf("*************     0.退出管理系统    **************\n");
    printf("**************************************************\n");
}
int main()
{
    int input = 0;
    //PeoInfo data[100];//存放100个人的信息,但是当我们进行增删查改一系列操作时,data里的实际有效元素,信息人的个数不断发生变化,需要变量记录一下
    //int count = 0;//用来记录通讯录里面联系人有多少,可以封装成一个结构体
    Contact con;//通讯录
    //初始化通讯录,可以用大括号初始化,之所以写函数来初始化,是为了让代码封装位模块的形式,另一方面是因为初始化的内容有些不能通过大括号来初始化
    InitContact(&con);//传址调用,1、节省空间,提高效率2、函数内部可以直接操作con的内容
    do
    {
        menu();
        printf("请选择:>\n");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            AddContact(&con);//也会修改通讯录内容因此采用传址传参
            break;
        case 2:
            DelContact(&con);
            break;
        case 3:
            SearchContact(&con);
            break;
        case 4:
            ModifyContact(&con);
            break;
        case 5:
            SortContact(&con);
            break;
        case 6:
            ShowContact(&con);
            break;
        case 0:
            printf("退出管理系统\n");
            break;
        default:
            printf("选择错误请重新选择\n");
            break;
        }
    } while (input);
    return 0;
}

//contact.c文件

#include"contact.h"
void InitContact(Contact* pc)
{
    pc->count = 0;
    memset(pc->data, 0, sizeof(pc->data));//memset内存设置函数:将指向内存块的字节设置为指定值,当然也可以通过循环来解决但较为麻烦
}
 static int FindbyName(Contact* pc,char name[])
{
    int i = 0;
    for (i = 0; i < pc->count; i++)
    {
        if (strcmp(pc->data[i].name,name)==0)
        {
            return i;
        }
    }
    return -1;
}
void AddContact(Contact* pc)
{
    if (pc->data == MAX)
    {
        printf("通讯录已满,无法进行添加操作\n");
        return;
    }
    //未满,进行添加操作
    printf("请输入名字:>");//如果data里面没有数据,count就为0,可以作为下标,count为1时说明里面有1个数据,下标为1
    scanf("%s", pc->data[pc->count].name);
    printf("请输入年龄:>");
    scanf("%d", &(pc->data[pc->count].age));
    printf("请输入性别:>");
    scanf("%s", pc->data[pc->count].sex);
    printf("请输入电话:>");
    scanf("%s", pc->data[pc->count].tel);
    printf("请输入地址:>");
    scanf("%s", pc->data[pc->count].addr);
    pc->count++;
    printf("增加成功\n");
}
void ShowContact(const Contact* pc)
{
    int i = 0;
    printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
    for (i = 0; i < pc->count; i++)
    {
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tel, pc->data[i].addr);
    }
}
void DelContact(Contact* pc)
{
    int i = 0;
    //我们可以按照名字来删除,当然也可以按照其他的来删除
    char name[MAX_NAME] = { 0 };//删除联系人的前提是数据不为空,所以我们应该先判断一下
    if (pc->count == 0)
    {
        printf("通讯录为空,无法删除\n");
        return;
    }
    printf("请输入将要删除联系人姓名:>");
    scanf("%s", name);
    //删除联系人分两步,先查找是否存在该联系人,若存在才可删除
    //1、查找
    int ret=FindbyName(pc, name);//因为查找联系人、删除、修改、都要查找,所以封装一个函数,若找到返回下标,反之返回-1
    if (ret == -1)
    {
        printf("该联系人不存在\n");
        return;
    }
    //2、删除,可以把后面的元素往前覆盖即可
    for (i = ret; i < pc->count-1; i++)
    {
        pc->data[i] = pc->data[i + 1];
    }
    pc->count--;
    printf("删除成功\n");
    //也可以用memove来删除:memmove(&(pc->data[ret]), &(pc->data[ret + 1]), (pc->count - ret) * (sizeof(Contact)));但必须保证通讯录中联系人信息是连续的
}
void SearchContact(Contact* pc)
{
    char name[MAX_NAME] = { 0 };
    printf("请输入将要查找联系人姓名:>");
    scanf("%s", name);
    int ret = FindbyName(pc, name);
    if (ret == -1)
    {
        printf("要查找的人不存在\n");
        return;
    }
    else
    {
        printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "住址");
        printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[ret].name, pc->data[ret].age, pc->data[ret].sex, pc->data[ret].tel, pc->data[ret].addr);
    }
}
void ModifyContact(Contact* pc)
{
    char name[MAX_NAME] = { 0 };
    printf("请输入将要修改联系人姓名:>");
    scanf("%s", name);
    int ret = FindbyName(pc, name);
    if (ret == -1)
    {
        char name[MAX_NAME] = { 0 };
        printf("该联系人不存在\n");
        return;
    }
    printf("请输入名字:>");
    scanf("%s", pc->data[ret].name);
    printf("请输入年龄:>");
    scanf("%d", &(pc->data[ret].age));
    printf("请输入性别:>");
    scanf("%s", pc->data[ret].sex);
    printf("请输入电话:>");
    scanf("%s", pc->data[ret].tel);
    printf("请输入地址:>");
    scanf("%s", pc->data[ret].addr);
    printf("修改成功\n");
}
int cmp_by_name(const char* e1, const char* e2)
{
    return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
    //假如按照名字排序,快排
    qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
    printf("排序成功\n");
}

 

 

 

 

 

 

  • 48
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 37
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值