C语言从入门到放弃——静态通讯录实现

news2024/11/23 9:07:38

目录

 一.功能实现

1.打印开始菜单

2.实现选择

3.初始化通讯录

4.添加、删除等功能实现

(1)添加联系人

(2)删除联系人

(3)查找联系人

(4)修改联系人

(5)显示所有联系人

(6)清空联系人

(7)排序联系人

二.模块调用

源码

addbook.h

addbook.c

test.c


通讯录,一种用于记录通讯地址的书本,在手机,电脑等电子设备中也拥有这种功能,它里面涵盖多种内容,如:姓名、年龄、性别、地址、电话等等,本文就用C语言带大家去实现静态通讯录。我们有几次实现游戏的经验,如扫雷、三子棋,这次同样是分成三个模块,一个用于实现功能,一个用于调用我们实现的功能,一个用于声明。

 一.功能实现

1.打印开始菜单

和三子棋扫雷一样,我们都需要有一个开始菜单,告诉使用者有那些功能,对于我们的通讯录来说,无非就是添加联系人、删除联系人、查找联系人、修改联系人等等,那和三子棋扫雷一样,我们先将这些制作到菜单当中,让使用者选择。

 

void menu()
{
	printf("************************************\n");
	printf("*****     1.添加     2.删除    *****\n");
	printf("*****     3.查找     4.修改    *****\n");
	printf("*****     5.显示     6.清空    *****\n");
	printf("*****     7.排序     0.退出    *****\n");
	printf("************************************\n");
}

2.实现选择

选择选择也于扫雷三子棋大同小异,利用dowhile语句来实现多次循环,因为这次选择的功能很多,所以我们采用switch语句。

int input = 0;
do
{
	menu();
	printf("请选择:>");
	scanf("%d", &input);
	switch(input)
	{
	case 1:
		break;
	case 2:
		break;
	case 3:
		break;
	case 4:
		break;
	case 5:
		break;		
    case 6:;
		break;
	case 7:
		break;
	case 0:
		printf("退出通讯录\n");
		break;
	default:
		printf("选择错误,请重新选择\n");
		break;
	}
} while (input);

3.初始化通讯录

我们要实现一个通讯录,那我们这些数据要放在哪里?这里就用到了我们的结构体,我们需要一个结构体,代表一个人的信息,名字,性别,地址这些,那我们还需要确定的是,我们这个通讯录能存多少个人的信息,那我们就假设我们通讯里可以存放一百个人的,那这一百个人,我们去存放的时候怎么知道我们存了多少个人了信息了呢?那这里我们就可以在用一个结构体,里面放我们存放信息的结构体数组,然后一个整型类型的变量,每次存放就加加,删除就减减。

struct addbook
{
	char name[20];
	int age;
	char gen[5];
	char loc[20];
	char ph[12];
};

typedef struct addbooks
{
	struct addbook s[100];
	int sz;
}addb;

那有了这些东西,在没有初始化之前,这些变量和数组里面存放的东西都是未知的,那就需要我们去初始化数组,我们可以直接用第二个结构体类型定义一个变量然后等于0,全初始化成0,我们也可以用一个函数menset来进行我们的初始化,将我们存放信息的数组内的初始化成我们想要的数值。

//初始化通讯录
void init_addbook(addb* ab)
{
	assert(ab);
	ab->sz= 0;
	memset(ab->s, 0, sizeof(ab->s));
}

4.添加、删除等功能实现

(1)添加联系人

添加联系人,这个函数实现逻辑很简单,我们每次添加之前,先确定我们的通讯录是有位置的,所以我们可以先对sz进行一个判断,如果它等于100,就告诉我们通讯录已满,如果没有,就将下标为sz的位置替换成我们想要输入的信息,然后sz加加。

//添加联系人
void add_book(addb* ab)
{
	assert(ab);
	if (ab->sz == MAX)
	{
		printf("通讯录已满");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s", ab->s[ab->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &(ab->s[ab->sz].age)); 
	printf("请输入性别:>");
	scanf("%s", ab->s[ab->sz].gen);
	printf("请输入地址:>");
	scanf("%s", ab->s[ab->sz].loc);
	printf("请输入电话:>");
	scanf("%s", ab->s[ab->sz].ph);
	printf("联系人添加成功\n");
	ab->sz++;
}

(2)删除联系人

删除联系人,我们可以采用输入名字,然后删除的方式,所以我们可以输入一个名字,然后开始对比数组内的每一个名字,相等就进去,跳出循环,然后开始让后面的信息往前面覆盖,最后让sz减减,这里我们要注意,我们后续实现的内容很多都要用到我们的查找,那我们就可以将查找部分分装成一个函数,返回一个整数,如果找不到,就返回-1,找到了,返回此时的下标位置。

//查找
int find_book(addb* ab)
{
	assert(ab);
	char ch[NAME_MAX] = { 0 };
	printf("请输入联系人姓名:>");
	scanf("%s", ch);
	int i = 0;
	for (; i < ab->sz; i++)
	{
		if (!strcmp(ab->s[i].name , ch))
		{
			return i;
		}
	}
	return -1;
}
//删除联系人
void del_book(addb* ab)
{
	assert(ab);
	int find = find_book(ab);
	if (-1==find)
	{
		printf("没有找到此人\n");
	}
	else
	{
		for (; find < ab->sz - 1; find++)
		{
			ab->s[find] = ab->s[find + 1];
		}
		ab->sz--;
	}
}

(3)查找联系人

查找就和我们的删除思路大概一样了,同样调用我们的查找函数,找不到返回-1,告诉我们没有这个人,然后跳出函数,但是后面找到就与删除不一样了,我们将返回下标对应的内容打印出来,就找到了,这里找到联系人之后,信息打印在屏幕上,但是没有提示,对于我们来说可能就有点难确定哪个是哪个,所以这里我们加一个表头,对应每个信息。

//查找联系人
void seek_book(addb* ab)
{
	assert(ab);
	int i = find_book(ab);
	if (i == -1)
	{
		printf("没有找到此联系人\n");
	}
	else
	{
		printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
			ab->s[i].age,
			ab->s[i].gen,
			ab->s[i].loc,
			ab->s[i].ph);
		
	}
}

(4)修改联系人

修改也是用我们的查找函数,查找不到就告诉我们没有,然后跳出,查找到了就修改。

//修改联系人
void amend_book(addb* ab)
{
	assert(ab);
	int i = find_book(ab);
	if (i == -1)
	{
		printf("没有找到此联系人\n");
	}
	else
	{
		printf("请输入姓名:>");
		scanf("%s", ab->s[i].name);
		printf("请输入年龄:>");
		scanf("%d", &(ab->s[i].age));
		printf("请输入性别:>");
		scanf("%s", ab->s[i].gen);
		printf("请输入地址:>");
		scanf("%s", ab->s[i].loc);
		printf("请输入电话:>");
		scanf("%s", ab->s[i].ph);
		printf("联系人修改成功\n");
	}
}

(5)显示所有联系人

我们要显示所有联系人,只用打印出我们数组的所有内容就可以,为了方便我们查看,也打印上表头。

//显示全部联系人
void show_book(addb* ab)
{
	assert(ab);
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (; i < ab->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
													ab->s[i].age,
													ab->s[i].gen,
													ab->s[i].loc,
													ab->s[i].ph);
	}

}

(6)清空联系人

清空联系人,也就是和我们的初始化一样,讲数组内容清空。

//初始化通讯录
void init_addbook(addb* ab)
{
	assert(ab);
	ab->sz= 0;
	memset(ab->s, 0, sizeof(ab->s));
}

(7)排序联系人

排序,我们可以用qsort,进行排序,用名字来进行排序。

//qsort
int name_sort(const void* s1, const void* s2)
{
	assert(s1 && s2);
	return strcmp((char*)s1, (char*)s2);
}

二.模块调用

对于我们的通讯录来说,不需要什么逻辑,我们只需要在选择对应的数字的时候,实行对应的功能即可。

源码

addbook.h

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

#define MAX 100
#define NAME_MAX 20
#define GEM_MAX 5
#define LOC_MAX 20
#define PH_MAX 12

struct addbook
{
	char name[NAME_MAX];
	int age;
	char gen[GEM_MAX];
	char loc[LOC_MAX];
	char ph[PH_MAX];
};

typedef struct addbooks
{
	struct addbook s[MAX];
	int sz;
}addb;

//功能实现
void init_addbook(addb* ab);//初始化通讯录
void add_book(addb* ab);//添加联系人
void del_book(addb* ab);//删除联系人
int find_book(addb* ab);//查找
void seek_book(addb* ab);//查找联系人
void amend_book(addb* ab);//修改联系人
void show_book(addb* ad);//显示全部联系人
int name_sort(const void* s1, const void* s2);//qsort

addbook.c

#include"addbook.h"

//初始化通讯录
void init_addbook(addb* ab)
{
	assert(ab);
	ab->sz= 0;
	memset(ab->s, 0, sizeof(ab->s));
}
//添加联系人
void add_book(addb* ab)
{
	assert(ab);
	if (ab->sz == MAX)
	{
		printf("通讯录已满");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s", ab->s[ab->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &(ab->s[ab->sz].age)); 
	printf("请输入性别:>");
	scanf("%s", ab->s[ab->sz].gen);
	printf("请输入地址:>");
	scanf("%s", ab->s[ab->sz].loc);
	printf("请输入电话:>");
	scanf("%s", ab->s[ab->sz].ph);
	printf("联系人添加成功\n");
	ab->sz++;
}
//查找
int find_book(addb* ab)
{
	assert(ab);
	char ch[NAME_MAX] = { 0 };
	printf("请输入联系人姓名:>");
	scanf("%s", ch);
	int i = 0;
	for (; i < ab->sz; i++)
	{
		if (!strcmp(ab->s[i].name , ch))
		{
			return i;
		}
	}
	return -1;
}
//删除联系人
void del_book(addb* ab)
{
	assert(ab);
	int find = find_book(ab);
	if (-1==find)
	{
		printf("没有找到此人\n");
	}
	else
	{
		for (; find < ab->sz - 1; find++)
		{
			ab->s[find] = ab->s[find + 1];
		}
		ab->sz--;
	}
}
//查找联系人
void seek_book(addb* ab)
{
	assert(ab);
	int i = find_book(ab);
	if (i == -1)
	{
		printf("没有找到此联系人\n");
	}
	else
	{
		printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
			ab->s[i].age,
			ab->s[i].gen,
			ab->s[i].loc,
			ab->s[i].ph);
		
	}
}
//修改联系人
void amend_book(addb* ab)
{
	assert(ab);
	int i = find_book(ab);
	if (i == -1)
	{
		printf("没有找到此联系人\n");
	}
	else
	{
		printf("请输入姓名:>");
		scanf("%s", ab->s[i].name);
		printf("请输入年龄:>");
		scanf("%d", &(ab->s[i].age));
		printf("请输入性别:>");
		scanf("%s", ab->s[i].gen);
		printf("请输入地址:>");
		scanf("%s", ab->s[i].loc);
		printf("请输入电话:>");
		scanf("%s", ab->s[i].ph);
		printf("联系人修改成功\n");
	}
}
//显示全部联系人
void show_book(addb* ab)
{
	assert(ab);
	printf("%-20s\t%-4s\t%-5s\t%-20s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	int i = 0;
	for (; i < ab->sz; i++)
	{
		printf("%-20s\t%-4d\t%-5s\t%-20s\t%-12s\n", ab->s[i].name,
													ab->s[i].age,
													ab->s[i].gen,
													ab->s[i].loc,
													ab->s[i].ph);
	}

}
//qsort
int name_sort(const void* s1, const void* s2)
{
	assert(s1 && s2);
	return strcmp((char*)s1, (char*)s2);
}

test.c

#include"addbook.h"

void menu()
{
	printf("************************************\n");
	printf("*****     1.添加     2.删除    *****\n");
	printf("*****     3.查找     4.修改    *****\n");
	printf("*****     5.显示     6.清空    *****\n");
	printf("*****     7.排序     0.退出    *****\n");
	printf("************************************\n");
}
int main()
{
	int input = 0;
	addb ab;
	init_addbook(&ab);
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch(input)
		{
		case 1:
			add_book(&ab);
			break;
		case 2:
			del_book(&ab);
			break;
		case 3:
			seek_book(&ab);
			break;
		case 4:
			amend_book(&ab);
			break;
		case 5:
			show_book(&ab);
			break;
		case 6:
			init_addbook(&ab);
			break;
		case 7:
			qsort(&ab, ab.sz, sizeof(ab.s[0]),name_sort);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158406.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】基于EasyX库的2048小游戏

文章目录0 前言1 先看一下最终的效果图2 2048核心2 EasyX库2.1 配色2.2 文字2.3 填充3 总结0 前言 最近比较迷2048小游戏&#xff0c;于是想自己写代码实现出来&#xff0c;恰好也在网上找到一个现成的2048的VS工程&#xff0c;但是界面做得很难看&#xff0c;且运行逻辑存在一…

研究发现,大多数长期 COVID 影响在感染后一年内消退

英国医学杂志今天发表的一项来自以色列的大型研究发现&#xff0c;轻度 COVID-19 感染后出现的大多数症状或病症会持续数月&#xff0c;但在一年内恢复正常。 特别是接种过疫苗的人&#xff0c;呼吸困难的风险较低。这通常也是轻度感染后最常见的影响。相比之下&#xff0c;比未…

【Day2】977有序数组的平方、209长度最小的子数组、59螺旋矩阵Ⅱ

【Day2】977有序数组的平方、209长度最小的子数组、59螺旋矩阵Ⅱ977有序数组的平方暴力排序双指针法209长度最小的子数组暴力解法滑动窗口法59螺旋矩阵Ⅱ977有序数组的平方 题目链接&#xff1a;977 题目&#xff1a;给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返…

Linux常用命令——xargs命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) xargs 给其他命令传递参数的一个过滤器 补充说明 xargs 命令是给其他命令传递参数的一个过滤器&#xff0c;也是组合多个命令的一个工具。它擅长将标准输入数据转换成命令行参数&#xff0c;xargs 能够处理管道…

python--城堡保卫战

实现功能&#xff1a; 1&#xff1a;敌人的绵绵不断的前进&#xff0c;拿着各种各样的武器&#xff08;叉子&#xff0c;斧头&#xff0c;宝剑&#xff09;&#xff0c;挥动武器攻击我方城堡&#xff0c;对我方城堡造成伤害&#xff01; 2&#xff1a;我方城堡发现敌人可手动…

Linux-文件系统

Windows文件系统 在Windows下&#xff0c;打开“计算机”&#xff0c;我们看到的是一个个驱动盘符。 注意&#xff1a;盘符与硬件不是对应的&#xff0c;比如说电脑有有一块硬盘&#xff0c;到Windows下可以将其切成C、D、E盘&#xff0c;也就是一个硬盘可以放多个盘符。 Lin…

maple-example简单操作示例

好久都没写博客了&#xff0c;今天学习到一点新知识&#xff0c;在这里小编和大家分享&#xff0c;欢迎大家指点&#xff0c;这篇文章是关于 maple-example的简单操作示例&#xff0c;具体软件下载不做讲解&#xff0c;谢谢&#xff01;

浅谈分辨率带宽RBW

频谱仪是射频工程师最常用的设备之一&#xff0c;信号的频率、功率、谐波、相位噪声等诸多射频参数都需要使用频谱仪测试。使用频谱仪时&#xff0c;有一个参数需要经常设置&#xff0c;就是分辨率带宽(Resolution BW&#xff0c;简称RBW)。RBW是指中频链路上最小的中频滤波器带…

Enhance the Visual Representation via Discrete Adversarial Training

在自然语言处理NLP中&#xff0c;AT可以从泛化中受益&#xff0c;我们注意到AT在NLP任务中的有优点可能来自于离散和符号输入空间。为了借鉴NLP风格AT的优势&#xff0c;我们提出了离散对抗训练&#xff08;DAT&#xff09;。DAT利用VQGAN将图像数据改为离散的类似文本的输入&a…

Vuex的学习内容

本教程使用的是vue3 1.核心概念 官网地址:https://vuex.vuejs.org/安装(固定)配置项(固定) 2. 图示关系 单一定义store对象,里面5个配置项,在任意组件可以使用. 3.案例准备 准备两个组件AddItem.vue、SubItem.vue、Main.vue 展示效果如下: AddItem代码 <template&…

STL - String容器

1. string基本概念 本质&#xff1a; string是C风格的字符串&#xff0c;而string本质上是一个类 string和char *的区别&#xff1a; char *是一个指针 string是一个类&#xff0c;类内部封装了char *,管理这个字符串&#xff0c;是一个char *型的容…

本地小说阅读网站打造

目录 一、本地小说网站总体组织框架 1、所需的VUE库和elementLib以及JQ库 2、本地目录设计 3、整体代码样式 二、正文核心代码 1、引入element 样式&#xff0c;和自定义的样式 2、引入JS 3、自定义Header组件 1&#xff09;vue 定义MyHeader组件 2&#xff09;MyHead…

Mapstruct的具体介绍与使用

我是 ABin-阿斌&#xff1a;写一生代码&#xff0c;创一世佳话&#xff0c;筑一览芳华。 如果小伙伴们觉得我的文章不错&#xff0c;记得一键三连哦 文章目录一、mapstruct简介二、mapstruct与其他映射对比三、mapstruct底层原理解析1、Java动态编译四、具体使用1、依赖导入2、…

Linux开发工具的使用(三)

文章目录Linux开发工具的使用&#xff08;三&#xff09;1. 缓冲区1.1 理解\r和\n1.2 缓冲区的初步理解1.3 倒计时小程序实现1.4 进度条小程序实现2. 分布式版本控制系统-git使用2.1 git历史2.2 git版本控制理解2.3 git使用2.3.1 gitee搭建远程仓库2.3.2 开始配置3. Linux调试器…

Revit教程:创建“幕墙竖梃族”的方法步骤

幕墙竖梃族分为两个组成部分&#xff1a;“幕墙竖梃”和“公制轮廓-竖梃”&#xff0c;前者是基于后者轮廓的一个实体拉伸&#xff0c;两者的关系类似于实体与草图。轮廓族及门窗族 (公制门-幕墙&#xff0c;公制窗-幕墙而非公制门与公制窗)可以嵌套入CAD详图或Revit详图&#…

93、【树与二叉树】leetcode ——222. 完全二叉树的节点个数:普通二叉树求法+完全二叉树性质求法(C++版本)

题目描述 原题链接&#xff1a;222. 完全二叉树的节点个数 解题思路 1、普通二叉树节点个数求法 &#xff08;1&#xff09;迭代&#xff1a;层序遍历BFS 遍历一层获取一层结点 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode …

【九】Netty HTTP+XML协议栈开发

HTTP协议介绍业务场景流程图技术栈设计流程图的分析:Step 1Step2Step3Step4Step5分析结果开发开发流程图代码jar 依赖代码结构如图pojo 包request包response 包client 包server包编码解码基类代码说明测试服务端打印结果客户端打印结果总结介绍 由于HTTP协议的通用性&#xff…

使用js实现一个可以【放烟花】的小游戏

放烟花游戏需求&#x1f447;核心玩法&#x1f447;&#x1f447;界面原型&#x1f447;&#x1f447;成品演示&#x1f447;游戏开发1.游戏素材准备2.代码实现1.创建index.html页面2.首页-开始3.加载烟花音效4.重玩儿放烟花的小游戏。点击页面放烟花。兼容移动端。 游戏需求 …

作为普通网民,这些“实用电脑神器”,值得你知道

国内软件夹缝里求生存&#xff0c;由于某些不良软件&#xff0c;许多人对于国产软件认识多为“流氓、捆绑、多广告”&#xff0c;其实并非如此&#xff0c;下面几款让你刮目相看&#xff0c;扭转观念。 1、图片视频画质增强器 这是一款功能极其强大的图片与视频画质增强器&…

阿里云数据湖3.0解决方案两度登上InfoQ 2022年度榜单

经过一个多月的层层竞选&#xff0c;【阿里云数据湖 3.0 解决方案】从 130 多个方案中脱颖而出&#xff0c;荣获 InfoQ 2022 年度中国技术力量年度榜单《十大云原生创新技术方案》&《云原生十大场景化落地方案》双料大奖&#xff0c;这是头部技术媒体对阿里云存储的再一次认…