C语言与C++动态通讯录超详细实现流程

 更新时间:2022年05月06日 14:41:33   作者:利刃Cc  
这篇文章主要为大家介绍了C语言与C++动态实现通讯录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

1、思路以及要实现的功能

通讯录就是为了存储许多联系人的不同方面的信息如名字、电话、地址、年龄、性别等,除此之外,还要实现增删查改还有打印通讯录等功能,所以我们先把要实现的功能列出来:

  • 增加联系人
  • 删除联系人
  • 搜索联系人
  • 修改联系人信息
  • 按年龄大小排序联系人
  • 打印联系人信息

2、详细步骤

2.1 打印菜单界面(建一个源文件test.c)

void menu()
{
	printf("********************************\n");
	printf("******  1.add    2.delete ******\n");
	printf("******  3.search 4.modify ******\n");
	printf("******  5.sort   6.print  ******\n");
	printf("************ 0.exit  ***********\n");
	printf("*******************************\n");
}

2.2 主函数

写出我们的主函数,利用do-while循环,并把即将要实现的功能先放在主函数内

在写函数之前,我们也要先定义一个结构体来存放联系人的信息还有联系人个数以及通讯录的最大容量,所以我们建一个头文件,称为contact.h,用来存放这些信息。

#pragma once
#include<stdio.h>
#define NAME_MAX 20//名字的最大长度
#define SEX_MAX 6
#define TELE_MAX 12//号码的最大位数
#define ADDR_MAX 30//地址的最大位数
#define ADD_PEO 1//每次拓展通讯录的人数
#define PEO_NUM 3//通讯录的初始容量
//类型的定义
typedef struct Peoinfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}Peoinfo;
typedef struct Contact
{
	Peoinfo *data;//指向动态申请的空间,存放联系人的信息
	int sz;//记录通讯录中有效信息的个数
	int capacity;//记录当前通讯录的最大容量
}Contact

除此之外,我们可以利用枚举将函数的选项封装一下!(存放在test.c)

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
}

这样子我们就可以写主函数啦!

#include "contact.h"
int main()
{
	Contact con;//创建通讯录
	InitContact(&con);//初始化通讯录
	int input=0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d",&input);
		switch(input)
		{
			case ADD:
			AddContact(&con);//增加人的信息
			break;
		case DEL:
			DelContact(&con);//删除人的信息
			break;
		case SEARCH:
			SearchContact(&con);//查找联系人
			break;
		case MODIFY:
			ModifyContact(&con);//修改信息
			break;
		case SORT:
			SortContact(&con);//排序
			break;
		case PRINT:
			PrintContact(&con);//打印通讯录
			break;
		case EXIT:
			SaveContact(&con);//保存通讯录
			DestoryContact(&con);//销毁信息
			printf("退出通讯录!\n");
			break;
		default:
			printf("选择错误!\n");
			break;
		}
	}while(input);
	return 0;
}

好啦!这样子我们就把轮廓写好了,现在就要一个个的实现每个函数的功能了!

2.3 初始化函数与加载函数

初始化函数InitContact与加载函数LoadContact

这里我们要先利用动态内存函数位信息开辟内存,然后用文件操作打开我们保存信息的文件中读取信息。

void InitContact(Contact* pc)
{
	pc->data=(Peoinfo*)malloc(PEO_NUM * sizeof(Peoinfo));
	if(pc->data==NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz=0;
	pc->capacity=PEO_NUM;

	LoadContact(pc);//加载已有的通讯录
}
void LoadContact(Contact* pc)
{
	File* pf = fopen("contact.txt","r");//创建或访问contact.txt读取信息
	if(pf == NULL)
	{
		perror("LoadContact");
		return;
	} 
	Peoinfo tmp={0};
	while(fread(&tmp,sizeof(Peoinfo),1,pf))
	{
		if(pc->sz==pc->capacity)
		{
			Peoinfo* ptr=(Peoinfo*)realloc(pc,(ADD_PEO+pc->capacity)sizeof(Peoinfo));
			if(ptr!=NULL)
			{
				pc->data=ptr;
				pc->capacity+=ADD_PEO;
			}
			else
			{
				perror("AddContact");
				printf("读取通讯录失败!\n");
				return;
			}
		}
		pc->data[pc->sz]=tmp;
		pc->sz++;
	}
	fclose(pf);
	pf=NULL;
}

这里我们创建一个Contact.c源文件来存放各自函数的功能,然后将函数的各个声明放到Contact.h中,以下也如此。

2.4 增加联系人函数AddContact

void AddContact(Contact* pc)
{
	if(pc->sz==pc->capacity)
	{
		(Peoinfo*)ptr=(Peoinfo*)realloc(pc,(ADD_PEO+pc->capacity) * sizeof(Peoinfo));
		if(ptr!=NULL)
		{
			pc->data=ptr;
			pc->capacity+=ADD_PEO;
		}
		else
		{
			perror("AddContact");
			printf("读取通讯录失败!\n");
			return;
		}
	}
	printf("请输入名字:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("增加成功!\n");
}

2.5 删除联系人函数DelContact

在实现该函数之前,我们发现,删除联系人函数与接下来的查找联系人、修改信息等函数有个共同的特点,那就是要先判断这个要做动作的联系人存不存在,所以考虑这点我们决定先封装一个FindByName函数用来判断这个人以及返回这个人信息的位置。

#include <string.h>	
static int FindByName(Contact* pc,char*name)
{
	int i=0;
	for(i=0;i<pc->sz;i++)
	{
		if(strcmp(pc->data[i].name,name)==0)
			return i;
	}
	return -1;
}

接下来我们就来实现删除联系人函数:

void DelContact(Contact* pc)
{
	char delname[NAME_MAX]={0};
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要删除人的名字:");
	scanf("%s", delname);
	//查找要删除的人
	int pos=FindByName(pc,delname);
	if(pos==-1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	else
	{
		int i=0;
		for(i=pos;i<pc->sz-1;i++)
		{
			pc->data[i]=pc->data[i+1];
		}
		pc->sz--;
		printf("删除联系人成功!\n");
	}
}

2.6 查找联系人函数与打印函数

查找联系人函数SearchContact与打印函数PrintContact

查找函数的功能是查找通讯录中是否有此人,并将其打印出来,所以我们可以顺便的把打印函数PrintContact实现。

void PrintContact(Contact* pc)
{
	//打印标题
	printf("****************************************************************************\n");
	printf("|姓名                |性别  |年龄  |电话号码    |地址                      |\n");
	if (pc->sz == 0)
	{
		printf("通讯录无信息!\n");
		printf("****************************************************************************\n");
		return;
	}
	for (int i = 0; i < pc->sz; i++)
	{
		printf("|%-20s|%-6s|%-6d|%-12s|%-26s|\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
	}
	printf("****************************************************************************\n");
	printf("\n");
}

接下来实现查找联系人函数:

void SearchContact(Contact* pc)
{
	char findname[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要查找的人的名字:");
	scanf("%s", findname);
	int pos=FindByName(pc,findname);
	if (pos == -1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	printf("****************************************************************************\n");
	printf("|姓名                |性别  |年龄  |电话号码    |地址                      |\n");
	printf("|%-20s|%-6s|%-6d|%-12s|%-26s|\n", pc->data[pos].name, pc->data[pos].sex, pc->data[pos].age, pc->data[pos].tele, pc->data[pos].addr);
	printf("****************************************************************************\n");
	printf("\n");
}

2.7 修改信息函数ModifyContact

void ModifyContact(Contact* pc)
{
	char findname[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要查找的人的名字:");
	scanf("%s", findname);
	int pos=FindByName(pc,findname);
	if (pos == -1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	printf("请输入名字:");
	scanf("%s", pc->data[pos].name);
	printf("请输入性别:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入电话:");
	scanf("%s", pc->data[pos].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pos].addr);
	printf("修改成功!\n");
}

2.8 排序函数SortContact

这里使用的是按年龄排序(冒泡排序),读者可按自己的需求实现不同的方法函数。

void SortContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录无信息,无法排序!\n");
		return;
	}
	int i=0,j=0;
	for(i=0;i<pz->sz-1;i++)
	{
		int flag=1;
		for(j=0;j<pz->sz-1-i;j++)
		{
			if(pz->data[j].age>pz->data[[j+1].age)
			{
				Peoinfo tmp[2];
				tmp[0] = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp[0];
				flag=0;
			}
		}
		if(flag==1)
			break;
	}
	printf("排序完成!\n");
}

2.9 保存信息函数与销毁数据函数

保存信息函数SaveContact与销毁数据函数DestoryContact

通讯录的大体功能我们都实现了,剩下的就是保存我们的信息到文本中与将各个数据置零了。我们先实现保存函数SaveContact:

void SaveContact(Contact* pc)
{
	File* pf=fopen("contact.txt","w");
	if(pf==NULL)
	{
		perror("SaveContact");
		return;
	}
	int i=0;
	for(i=0;i<pc->sz;i++)
	{
		fwrite(pc->data+i,sizeof(Peoinfo),1,pf);
	}
	fclose(pf);
	pf=NULL;
}

实现下面的销毁数据函数DestoryContact:

void DestoryContact(Contact* pc)
{
	free(pc->data);
	pc->data=NULL;
	pc->sz=0;
	pc->capacity=0;
}

完结撒花!!

3、源码

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "contact.h"
void menu()
{
	printf("********************************\n");
	printf("******  1.add    2.delete ******\n");
	printf("******  3.search 4.modify ******\n");
	printf("******  5.sort   6.print  ******\n");
	printf("************ 0.exit  ***********\n");
	printf("*******************************\n");
}
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};
int main()
{
	Contact con;//创建通讯录
	InitContact(&con);//初始化通讯录
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			AddContact(&con);//增加人的信息
			break;
		case DEL:
			DelContact(&con);//删除人的信息
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SORT:
			SortContact(&con);
			break;
		case PRINT:
			PrintContact(&con);//打印通讯录
			break;
		case EXIT:
			SaveContact(&con);//保存通讯录
			DestoryContact(&con);
			printf("退出通讯录!\n");
			break;
		default:
			printf("选择错误!\n");
			break;
		}
	} while (input);
	return 0;
}

contact.h

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 6
#define TELE_MAX 12
#define ADDR_MAX 30
#define ADD_PEO 1
#define PEO_NUM 3
//#define PEO_MAX 1000
//类型的定义
typedef struct Peoinfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
}Peoinfo;
//动态版本
typedef struct Contact
{
	Peoinfo *data;//指向动态申请的空间,存放联系人的信息
	int sz;//记录通讯录中有效信息的个数
	int capacity;//记录当前通讯录的最大容量
}Contact;
//初始化通讯录
void InitContact(Contact* pc);
//增加人的信息
void AddContact(Contact* pc);
//打印通讯录
void PrintContact(const Contact* pc);
//输出人的信息
void DelContact(Contact* pc);
//按名字查找
int FindByName(Contact* pc, char* name);
//查找信息
void SearchContact(Contact* pc);
//修改信息
void ModifyContact(Contact* pc);
//排序信息
void SortContact(Contact* pc);
//销毁通讯录
void DestoryContact(Contact* pc);
//保存通讯录
void SaveContact(Contact* pc);
//加载通讯录
void LoadContact(Contact* pc);

contact.c

#define _CRT_SECURE_NO_WARNINGS
#include "contact.h"
void LoadContact(Contact* pc)
{
	FILE* pf = fopen("contact.txt", "r");
	if (pf == NULL)
	{
		perror("LoadContact");
		return;
	}
	Peoinfo tmp = { 0 };
	while (fread(&tmp, sizeof(Peoinfo), 1, pf))
	{
		if (pc->sz == pc->capacity)
		{
			Peoinfo* ptr = (Peoinfo*)realloc(pc->data, (pc->capacity + ADD_PEO) * sizeof(Peoinfo));
			if (ptr != NULL)
			{
				pc->data = ptr;
				pc->capacity+=ADD_PEO;
			}
			else
			{
				perror("AddContact");
				printf("读取通讯录失败!\n");
				return;
			}
		}
		pc->data[pc->sz] = tmp;
		pc->sz++;
	}
	fclose(pf);
	pf = NULL;
}
void InitContact(Contact* pc)
{
	pc->data = (Peoinfo*)malloc(PEO_NUM * sizeof(Peoinfo));
	if (pc->data == NULL)
	{
		perror("InitContact");
		return;
	}
	pc->sz = 0;
	pc->capacity = PEO_NUM;
	//加载通讯录
	LoadContact(pc);
}
void AddContact(Contact* pc)
{
	if (pc->sz == pc->capacity)
	{
		Peoinfo* ptr = (Peoinfo*)realloc(pc->data, (pc->capacity + ADD_PEO) * sizeof(Peoinfo));
		if (ptr != NULL)
		{
			pc->data=ptr;
			pc->capacity += ADD_PEO;
			printf("增加容量成功!\n");
		}
		else
		{
			perror("AddContact");
			printf("增加联系人失败!\n");
			return;
		} 
	}
	printf("请输入名字:");
	scanf("%s", pc->data[pc->sz].name);
	printf("请输入性别:");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入电话:");
	scanf("%s", pc->data[pc->sz].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pc->sz].addr);
	pc->sz++;
	printf("增加成功!\n");
}
void PrintContact(const Contact* pc)
{
	//打印标题
	printf("****************************************************************************\n");
	printf("|姓名                |性别  |年龄  |电话号码    |地址                      |\n");
	if (pc->sz == 0)
	{
		printf("通讯录无信息!\n");
		printf("****************************************************************************\n");
		return;
	}
	for (int i = 0; i < pc->sz; i++)
	{
		printf("|%-20s|%-6s|%-6d|%-12s|%-26s|\n", pc->data[i].name, pc->data[i].sex, pc->data[i].age, pc->data[i].tele, pc->data[i].addr);
	}
	printf("****************************************************************************\n");
	printf("\n");
}
static int FindByName(Contact* pc,char* name)
{
	for (int i = 0; i < pc->sz; i++)
	{
		if (strcmp( pc->data[i].name,name) == 0)
			return i;
	}
	return -1;
}
void DelContact(Contact* pc)
{
	char delname[NAME_MAX]={0};
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要删除人的名字:");
	scanf("%s", delname);
	//查找要删除的人
	int pos =FindByName(pc, delname);
	if (pos == -1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	for (int i = pos; i < pc->sz-1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;
	printf("删除成功!\n");
}
void SearchContact(Contact* pc)
{
	char findname[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要查找的人的名字:");
	scanf("%s", findname);
	int pos = FindByName(pc, findname);
	if (pos == -1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	printf("****************************************************************************\n");
	printf("|姓名                |性别  |年龄  |电话号码    |地址                      |\n");
	printf("|%-20s|%-6s|%-6d|%-12s|%-26s|\n", pc->data[pos].name, pc->data[pos].sex, pc->data[pos].age, pc->data[pos].tele, pc->data[pos].addr);
	printf("****************************************************************************\n");
	printf("\n");
}
void ModifyContact(Contact* pc)
{
	char findname[NAME_MAX] = { 0 };
	if (pc->sz == 0)
	{
		printf("通讯录为空,无须删除!\n");
		return;
	}
	printf("请输入要查找的人的名字:");
	scanf("%s", findname);
	int pos = FindByName(pc, findname);
	if (pos == -1)
	{
		printf("查无此人的信息!\n");
		return;
	}
	printf("请输入名字:");
	scanf("%s", pc->data[pos].name);
	printf("请输入性别:");
	scanf("%s", pc->data[pos].sex);
	printf("请输入年龄:");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入电话:");
	scanf("%s", pc->data[pos].tele);
	printf("请输入住址:");
	scanf("%s", pc->data[pos].addr);
	printf("修改成功!\n");
}
void SortContact(Contact* pc)
{
	if (pc->sz == 0)
	{
		printf("通讯录无信息,无法排序!\n");
		return;
	}
	for (int i = 0; i < pc->sz - 1; i++)
	{
		int flag = 1;
		for (int j = 0; j < pc->sz - 1 - i; j++)
		{
			if (pc->data[j].age > pc->data[j + 1].age)
			{
				Peoinfo tmp[2];
				tmp[0] = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp[0];
				flag = 0;
			}
		}
		if (flag == 1)
			break;
	}
	printf("排序完成!\n");
}
void DestoryContact(Contact* pc)
{
	free(pc->data);
	pc -> data = NULL;
	pc->capacity = 0;
	pc->sz = 0;
}
void SaveContact(Contact* pc)
{
	FILE* pf = fopen("contact.txt", "w");
	if (pf == NULL)
	{
		perror("SaveContact");
		return;
	}
	for (int i = 0; i < pc->sz; i++)
	{
		fwrite(pc->data + i, sizeof(Peoinfo), 1, pf);
	}
	fclose(pf);
	pf = NULL;
}

到此这篇关于C语言与C++动态通讯录超详细实现流程的文章就介绍到这了,更多相关C语言动态通讯录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 用贪心法求解背包问题的解决方法

    用贪心法求解背包问题的解决方法

    本篇文章是对用贪心法求解背包问题的解决方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言实现选择排序、直接插入排序、冒泡排序的示例

    C语言实现选择排序、直接插入排序、冒泡排序的示例

    这篇文章主要介绍了C++实现选择排序、直接插入排序、冒泡排序的代码示例,相当简洁直观,也是算法和数据结构学习中的基础,需要的朋友可以参考下
    2016-02-02
  • C++实现路口交通灯模拟系统

    C++实现路口交通灯模拟系统

    这篇文章主要为大家详细介绍了C++实现路口交通灯模拟系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 新手socket编程入门详解指南

    新手socket编程入门详解指南

    本文,将一步一步引导初学者来学习socket,所有编程思路都结合在socket API里面,以及提供socket的疑问和基础知识点,同时在最后给出多个例程,下面可以和小编一起学习
    2019-05-05
  • C++动态调用动态链接库(DLL或SO)的方法实现

    C++动态调用动态链接库(DLL或SO)的方法实现

    动态链接库是一种Windows操作系统下常见的可执行文件格式,它包含了一些可被其他应用程序调用的函数和数据,本文主要介绍了C++动态调用动态链接库(DLL或SO),感兴趣的可以了解一下
    2024-01-01
  • C++使用正则表达式的详细教程

    C++使用正则表达式的详细教程

    正则表达式是一个非常强大的工具,主要用于字符串匹配,下面这篇文章主要给大家介绍了关于C++使用正则表达式的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • C语言实现学生奖学金评定系统

    C语言实现学生奖学金评定系统

    这篇文章主要介绍了C语言实现学生奖学金评定系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • c++多线程之死锁的发生的情况解析(包含两个归纳,6个示例)

    c++多线程之死锁的发生的情况解析(包含两个归纳,6个示例)

    这篇文章主要介绍了c++多线程之死锁的发生的情况解析(包含两个归纳,6个示例),需要的朋友可以参考下
    2018-01-01
  • C++中的异常处理机制详解

    C++中的异常处理机制详解

    本文给大家分享的是C++中的异常处理机制。对如何处理异常、基本异常语法、异常保护代码等进行了探讨,推荐给大家。
    2017-04-04
  • Qt菜单QMenu和菜单栏QMenuBar及自定义菜单用法

    Qt菜单QMenu和菜单栏QMenuBar及自定义菜单用法

    本文主要介绍了Qt菜单QMenu和菜单栏QMenuBar及自定义菜单用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05

最新评论