【c语言】通讯录(静态)

news2024/11/26 13:35:57

小张刚学习完结构体,枚举,联合相关的知识,实践实践,写一个通讯录呗!


通讯录的功能

1.通讯录可存放100的信息
2.信息的内容姓名,性别,年龄,电话,地址
3.支持增加联系人
4.支持删除联系人
5.支持查找联系人
6.支持修改联系人
7.支持排序联系人
8.打印数据

文件类型

test.c(测试通讯录相关功能)
contanct.c(通讯录功能的实现)
contanct.h(声明)

一个人信息在结构体中定义

struct peoinfo {
char name[20];姓名
char sex[5];性别
int age;年龄
char tel[12];电话
char addr[20];};地址

为了方便代码的可读性,我们在宏里面定义每个字符串数组的长度,修改如下

struct peoinfo {
char name[MAX_NAME];姓名
char sex[MAX_SEX];性别
int age;年龄
char tel[MAX_TEL];电话
char addr[MAX_ADDR];地址};

宏定义如下

#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TEL 12
#define MAX_ADDR 20
#define MAX 1000

通讯录用结构体

typedef struct pp{
struct peoinfo arr[MAX];
int sz;}pp;
用typedef将通讯录结构体类型重命名为pp,方便操作
在这里插入图片描述

菜单函数menu

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

}

选择功能函数test()

void test()
{pp pro;//定义一个通讯录
Initcontanct(&pro);//通讯录初始化,具体在下面
int input;
	do {
		menu();
		scanf_s("%d", &input);
		switch (input)
		{
		case 1:
			Addcontanct(&pro);
			break;
		case 2:
			Delcontanct(&pro);
			break;
		case 3:
			findcontanct(&pro);
			break;
		case 4:
			modifycontanct(&pro);
			break;
		case 5:
			Sortcontanct(&pro);
			break;
		case 6:
			Printcontanct(&pro);
			break;
		case 7:
			
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}

switch语句中的case1,2,3,4不好对应功能,为了提高代码可读性,我们可以定义一个枚举类型
enum opion
{
EXIT,//他的值为0,下面依次1,2,3,4,5,6
ADD,
DEL,
SEARCH,
MODIFY,
SORT,
PRINT
};

test()函数修改

void test()
{pp pro;
Initcontanct(&pro);
int input;
	do {
		menu();
		scanf_s("%d", &input);
		switch (input)
		{
		case  ADD:
			Addcontanct(&pro);
			break;
		case DEL:
			Delcontanct(&pro);
			break;
		case SEARCH:
			findcontanct(&pro);
			break;
		case MODIFY:
			modifycontanct(&pro);
			break;
		case SORT:
			Sortcontanct(&pro);
			break;
		case PRINT:
			Printcontanct(&pro);
			break;
		
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}

初始化通讯录函数

作用:将sz初始化为0,将struct peoinfo arr[]初始化为0,防止初始化为随机值,memset函数可以将从哪个地址开始多少个字节置为你想置的数,第一个参数是从哪个地址开始重置,第二个参数是置为什么,第三个参数是置多少个字节,memset头文件stdlib.h

void Initcontanct(pp*p)
{
	p->sz = 0;
	memset(p->arr, 0, sizeof(p->arr));
}

结构体指针p接收通讯录的地址&pro

添加联系人

void Addcontanct(pp* p)
{
	if (p->sz == 1000)
	{
		printf("通讯录已经存满\n");
		return;
	}
	printf("请输入姓名\n");
	scanf("%s",p->arr[p->sz].name);
	printf("请输入性别\n");
	scanf("%s",p->arr[p->sz].sex);
	printf("请输入年龄\n");
	scanf("%d",&(p->arr[p->sz].age));
	printf("请输入电话\n");
	scanf("%s",p->arr[p->sz].tel);
	printf("请输入地址\n");
	scanf("%s",p->arr[p->sz].addr);
	p->sz++;
	printf("录入成功\n");

}

注意年龄不是数组,scanf的时候必须加&取地址符,每次添加1个,p->sz+1;如果==1000,表示已经存满,return直接跳出,不再进行添加过程

打印数据函数

void Printcontanct(pp* p)
{
	int i = 0;
	printf("******************************************************\n");
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址");
	printf("******************************************************\n");
	for (i = 0; i < p->sz; i++)
	{
		printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr);
		printf("******************************************************\n");
	}
}

注意:为了能打印更加美观,打印采用左对齐,打印*的每行为了将用户分开,更好看一点,循环遍历通讯录每个成员,将其打印,每个用户打印完了,记得换行

删除联系人

void Delcontanct(pp* p)
{
	char name[MAX_NAME];
	printf("请输入要删除朋友的名字\n");
	scanf("%s",name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		for (int j = k; j < p->sz - 1; j++)
		{
			p->arr[j] = p->arr[j + 1];
		}
		p->sz--;
		printf("删除成功\n");

}
}

查找函数find()

int find(pp* p, char name[])
{
	int i = 0;
	for (int i = 0; i < p->sz; i++)
	{
		if (!strcmp(p->arr[i].name, name))
			return i;
	}
	return -1;
}

注意查找函数的功能是遍历通讯录,如果有此人,返回这个人数组的下标,如果没有此人,返回-1;使用strcmp比较函数记得头文件string.h,删除一个人,输入要删除的那个人的名字,将输入名字的数组地址和通讯录的地址传给find()函数,调用find()函数遍历通讯录,如果没有此人,find()函数返回-1;打印查无此人,否则用k接收其要删除用户的下标,将k下标的用户删除,然后将后面的依次向前挪,删除一个,对应的p->sz- -

查找联系人

void findcontanct(pp* p)
{
	char name[MAX_NAME];
	if (p->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入要查找朋友的名字\n");
	scanf("%s", name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		printf("******************************************************\n");
		printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr);
		printf("******************************************************\n");
	}
}

注意:查找基本和删除类似,输入名字后,需要调用find函数查找对应名字的下标,返回-1;表示没找到,如果返回了下标将这个下标对应的信息打印出来

修改联系人信息

void modifycontanct(pp* p)
{
	char name[MAX_NAME];
	printf("请输入修改朋友的名字\n");
	scanf("%s", name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		printf("请输入要修改朋友的信息\n");
		printf("修改性别->");
		scanf("%s", p->arr[k].sex);
		printf("修改年龄->");
		scanf("%d", &(p->arr[k].age));
		printf("修改电话->");
		scanf("%s", p->arr[k].tel);
		printf("修改地址->");
		scanf("%s", p->arr[k].addr);
		printf("修改成功\n");
     }
}

注意修改联系人信息还是需要find()函数查找联系人名字,find()函数返回其下标,修改的时候,直接对下标对应的用户进行操作,年龄不是数组,scanf需要加&取地址符

排序联系人(年龄排序)

void Sortcontanct(pp* p)
{
	int i = 0;
	for (int i = 0; i < p->sz-1; i++)
	{
		for (int j = 0; j < p->sz - i-1; j++)
		{
			if (p->arr[j].age > p->arr[j + 1].age)
			{
				int tmp = p->arr[j].age;
				p->arr[j].age = p->arr[j + 1].age;
				p->arr[j + 1].age = tmp;
				char name[MAX_NAME];
				strcpy(name, p->arr[j].name);
				strcpy(p->arr[j].name, p->arr[j+1].name);
				strcpy(p->arr[j + 1].name, name);

				char sex[MAX_SEX];
				strcpy(sex, p->arr[j].sex);
				strcpy(p->arr[j].sex, p->arr[j + 1].sex);
				strcpy(p->arr[j + 1].sex, sex);

				char tel[MAX_TEL];
				strcpy(tel, p->arr[j].tel);
				strcpy(p->arr[j].tel, p->arr[j + 1].tel);
				strcpy(p->arr[j + 1].tel, tel);

				char addr[MAX_ADDR];
				strcpy(addr, p->arr[j].addr);
				strcpy(p->arr[j].addr, p->arr[j + 1].addr);
				strcpy(p->arr[j + 1].addr, tel);


             }



		}
}
	printf("按年龄排序成功,快去打印吧\n");
}

注意利用冒泡排序按年龄从小到大排序,将年龄交换的同时,需要将两个人的名字,性别,电话,住址也进行交换,字符串数组,我们采用strcpy,strcpy头文件string.h,交换的思想也是用到了三个数交换的灵感

但是我的上一篇讲的是qsort排序,我们也可以用qsort进行排序,拒绝屎山代码

修改:排序联系人

int int_cmp_age(const void* p1, const void* p2)//按年龄比较
{
	return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age;
}
void Sortcontanct(pp* p)
{
	qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age);
    printf("按年龄排序成功,快去打印吧\n");
}

整体代码展示
contanct.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX_NAME 20
#define MAX_SEX 6
#define MAX_TEL 12
#define MAX_ADDR 20
#define MAX 1000
enum opion
{
	EXIT,
    ADD,
	DEL,
    SEARCH,
	MODIFY,
	SORT,
	PRINT
};
typedef struct peoinfo {
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tel[MAX_TEL];
	char addr[MAX_ADDR];

}peoinfo;

typedef struct pp{
	struct peoinfo arr[MAX];
	int sz;

}pp;
void Initcontanct(pp*p);
void Addcontanct(pp* p);
void Printcontanct(pp* p);
void Delcontanct(pp* p);
void findcontanct(pp* p);
void modifycontanct(pp* p);
void Sortcontanct(pp* p);

contanct.c

#include"contanct.h"
void Initcontanct(pp*p)
{
	p->sz = 0;
	memset(p->arr, 0, sizeof(p->arr));
}
void Addcontanct(pp* p)
{
	if (p->sz == 1000)
	{
		printf("通讯录已经存满\n");
		return;
	}
	printf("请输入姓名\n");
	scanf("%s",p->arr[p->sz].name);
	printf("请输入性别\n");
	scanf("%s",p->arr[p->sz].sex);
	printf("请输入年龄\n");
	scanf("%d",&(p->arr[p->sz].age));
	printf("请输入电话\n");
	scanf("%s",p->arr[p->sz].tel);
	printf("请输入地址\n");
	scanf("%s",p->arr[p->sz].addr);
	p->sz++;
	printf("录入成功\n");

}
void Printcontanct(pp* p)
{
	int i = 0;
	printf("******************************************************\n");
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名","性别","年龄","电话","地址");
	printf("******************************************************\n");
	for (i = 0; i < p->sz; i++)
	{
		printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[i].name, p->arr[i].sex, p->arr[i].age, p->arr[i].tel, p->arr[i].addr);
		printf("******************************************************\n");
	}
}
int find(pp* p, char name[])
{
	int i = 0;
	for (int i = 0; i < p->sz; i++)
	{
		if (!strcmp(p->arr[i].name, name))
			return i;
	}
	return -1;
}
void Delcontanct(pp* p)
{
	char name[MAX_NAME];
	printf("请输入要删除朋友的名字\n");
	scanf("%s",name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		for (int j = k; j < p->sz - 1; j++)
		{
			p->arr[j] = p->arr[j + 1];
		}
		p->sz--;
		printf("删除成功\n");

}
}
void findcontanct(pp* p)
{
	char name[MAX_NAME];
	if (p->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入要查找朋友的名字\n");
	scanf("%s", name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		printf("******************************************************\n");
		printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-10s %-5s %-5d %-12s %-20s\n", p->arr[k].name, p->arr[k].sex, p->arr[k].age, p->arr[k].tel, p->arr[k].addr);
		printf("******************************************************\n");
	}
}
void modifycontanct(pp* p)
{
	char name[MAX_NAME];
	printf("请输入修改朋友的名字\n");
	scanf("%s", name);
	if (find(p, name) == -1)
	{
		printf("查无此人\n");
	}
	else
	{
		int k = find(p, name);
		printf("请输入要修改朋友的信息\n");
		printf("修改性别->");
		scanf("%s", p->arr[k].sex);
		printf("修改年龄->");
		scanf("%d", &(p->arr[k].age));
		printf("修改电话->");
		scanf("%s", p->arr[k].tel);
		printf("修改地址->");
		scanf("%s", p->arr[k].addr);
		printf("修改成功\n");
     }
}
int int_cmp_age(const void* p1, const void* p2)//按年龄比较
{
	return ((struct peoinfo*)p1)->age - ((struct peoinfo*)p2)->age;
}
void Sortcontanct(pp* p)
{
	qsort(p->arr, p->sz, sizeof(peoinfo), int_cmp_age);
    printf("按年龄排序成功,快去打印吧\n");
}

test.c

#include"contanct.h"
void menu()
{
	printf("#######################################\n");
	printf("#*********    1.add    ***************#\n");
	printf("#*********    2.del    ***************#\n");
	printf("#*********    3.search ***************#\n");
	printf("#*********    4.modify ***************#\n");
	printf("#*********    5.sort   ***************#\n");
	printf("#*********    6.print  ****************#\n");
	printf("##########    0.exit   ################\n");

}
void test()
{pp pro;
Initcontanct(&pro);
int input;
	do {
		menu();
		scanf_s("%d", &input);
		switch (input)
		{
		case  ADD:
			Addcontanct(&pro);
			break;
		case DEL:
			Delcontanct(&pro);
			break;
		case SEARCH:
			findcontanct(&pro);
			break;
		case MODIFY:
			modifycontanct(&pro);
			break;
		case SORT:
			Sortcontanct(&pro);
			break;
		case PRINT:
			Printcontanct(&pro);
			break;
		
		case EXIT:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);
}

void main()
{
	test();

}

结果展示
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
存在的问题大家可以指出,后面会和大家分享动态通讯录,大家多多支持,还有就是我访问终于破2000了哈哈哈哈哈
彩蛋
在这里插入图片描述
今天分享就到这里,下一篇见

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

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

相关文章

许可是开源的基石,协作才是未来! KCC@南京第二次活动

自从疫情结束后&#xff0c;作为“穷游”之城的南京&#xff0c;且具有高性价比的六朝古都&#xff0c;来旅行的人们也是络绎不绝&#xff0c;恰逢暑假之时更为火爆。即便在炎炎夏日&#xff0c;也依然抵挡不住开源人的那颗赤诚之心。 此次活动不仅是本地的开源人&#xff0c;花…

树莓派RP2040 用Arduino IDE安装和编译

目录 1 Arduino IDE 1.1 IDE下载 1.2 安装 arduino mbed os rp2040 boards 2 编程-烧录固件 2.1 打开点灯示例程序 2.2 选择Raspberry Pi Pico开发板 2.3 编译程序 2.4 烧录程序 2.4.1 Raspberry Pi Pico开发板首次烧录提示失败 2.4.2 解决首次下载失败问题 2.4.2.1…

uniapp的UI框架组件库——uView

在写uniapp项目时候&#xff0c;官方所推荐的样式库并不能满足日常的需求&#xff0c;也不可能自己去写相应的样式&#xff0c;费时又费力&#xff0c;所以我们一般会去使用第三方的组件库UI&#xff0c;就像vue里我们所熟悉的elementUI组件库一样的道理&#xff0c;在uniapp中…

基于grpc从零开始搭建一个准生产分布式应用(1) - 开始准备

开始前必读&#xff1a;​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 本来笔者并不想开设这个系列&#xff0c;因为工作量比较大&#xff0c;另外此专题的技术点也偏简单。最近复盘了下最近的工作&#xff0c;发现一个问题就是各个互联网大厂一般都会有…

hbase 报错 Master passed us a different hostname to use; was=

原因 wsl2的 /etc/hosts 配置的不兼容,我这里是ubuntu22 修改为 127.0.0.1 ubuntu22 即可

Blazor 调试控制台

文章目录 设置 设置 Blazor项目启动之后&#xff0c;有好几种项目设置&#xff0c;我其实想要这一种控制台 直接Console.log就行了 public void LoginBtn(){Console.WriteLine("登录");//navigationManager.NavigateTo("/index");}

STM32 LL库开发

一、STM32开发方式 标准库开发&#xff1a;Standard Peripheral Libraries&#xff0c;STDHAL库开发&#xff1a;Hardware Abstraction Layer&#xff0c;硬件抽象层LL库开发&#xff1a;Low-layer&#xff0c;底层库 二、HAL库与LL库开发对比 ST在推行HAL库的时候&#xff0c;…

手机怎样换ip地址 更改手机IP地址有哪些方式

ip地址怎么改&#xff1a;使用深度ip转换器 在互联网时代&#xff0c;IP地址扮演着网络世界中的独特标识符。它是我们在上网时必不可少的元素&#xff0c;负责为设备提供独立的身份&#xff0c;并将信息传输到正确的目的地。然而&#xff0c;有时我们需要改变IP地址&#xff0c…

婚恋交友h5多端小程序开源版开发

婚恋交友h5多端小程序开源版开发 以下是婚恋交友H5多端小程序的功能列表&#xff1a; 用户注册和登录&#xff1a;用户可以通过手机号码或第三方账号注册和登录。个人信息填写&#xff1a;用户可以填写个人基本信息&#xff0c;包括姓名、性别、年龄、身高、体重、学历、职业等…

第11集丨Vue 江湖 —— 过滤器(filter)

目录 一、过滤器1.1 局部过滤器1.2 全局过滤器1.3 过滤器的串联1.4 案例 二、BootCDN2.1 在BootCDN下载dayjs2.2 dayjs官方文档 一、过滤器 过滤器&#xff1a; 定义&#xff1a;对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理&#xff09;。语法: a. 注册过…

阿里巴巴面试题---考察对底层源代码的熟悉程度

题目如图所示: 很多人可能会觉得两个输出都会是false,因为我们都会觉得""比较的是引用类型的地址,虽然放入的值都一样但是重新创造了新对象,地址不一样,所以结果都是false. 然而,当我们运行程序会发现结果都是false. 下面,我们来分析为什么是这样的结果. 我们知道…

nodejs+vue+elementui健身俱乐部网站rix1z

为设计一个安全便捷&#xff0c;并且使用户更好获取本健身俱乐部管理信息&#xff0c;本文主要有安全、简洁为理念&#xff0c;实现用户快捷寻找健身课程、健身器材、会员卡信息、新闻公告等信息&#xff0c;从而解决健身俱乐部管理信息复杂难辨的问题。该系统以vue架构技术为基…

Linux 目录和文件常见操作

就常见的命令&#xff1a; pwd pwd 显示当前的目录 目录迁移 我以如下的目录大致结构做一个简单的例子 cd 迁移到指定的路径&#xff0c;可以指定相对路径和绝对路径&#xff0c;默认相对 .指向当前路径&#xff0c;…/ 指向上一级的目录。 ls 列出文件及其目录 命令选…

取个对象值导致系统崩溃

取个对象值导致系统崩溃 前言 想必各位小伙经常在项目中遇到一些错误&#xff0c;取对象值的时候&#xff0c;经常报错,又或者某些项目突然就挂经常都是出现在一些对象取值上面&#xff0c;然后就被领导一顿训斥 报错分析 例如&#xff1a; 下面这个报错大家想必不会陌生&am…

华尔街之狼

&#xff08;1&#xff09; 我最近在重看一本书《物理学家走进华尔街》&#xff0c;顺便我还又重看了一遍《华尔街之狼》。 华尔街之狼&#xff0c;我最感兴趣三点&#xff1a; 垃圾产品&#xff1a;退市的垃圾股粉单 垃圾顾客&#xff1a;没有钱&#xff0c;但想发财的平民。就…

掌握Python的X篇_28_python包管理工具pip命令

本篇将会介绍在实际使用python中最能节省效率的内容&#xff0c;利用第三方库拿来就用。 文章目录 1. pip命令是什么2. pip相关操作2.1 list2.2 install2.3 uninstall2.4 导出和导入2.4.1 freeze命令2.4.2 “-r” 3. 国内镜像4. Python Packges Index网站 1. pip命令是什么 p…

mysql安装配置教程

mysql下载 mysql官网 mysql英文官网下载 mysql安装 解压安装包,如下效果 2.配置初始化文件my.ini 在根目录下创建一个txt文件&#xff0c;名字叫my&#xff0c;文件后缀为ini 之后复制下面这个代码放在文件下 &#xff08;新解压的文件没有my.ini文件&#xff0c;需自行创建…

QT界面的布局

QT界面的布局 qt 下的布局: 1.水平布局2.垂直布局3格布局 图片记得设置大小后在进行布局 文字居中

c++11-14-17_内存管理(RAII)_多线程

文章目录 前言&#xff1a;什么是RAII&#xff1f;指针/智能指针&#xff1a;使用智能指针管理内存资源&#xff1a;unique_ptr的使用&#xff1a;自定义删除器&#xff1a; shared_ptr的使用&#xff1a;shared_ptr指向同一个对象的不同成员&#xff1a;自定义删除函数&#x…

时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测)

时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测) 目录 时序预测 | Python实现LSTM长短期记忆网络时间序列预测(电力负荷预测)效果一览基本描述模型结构程序设计参考资料效果一览