【C语言】通讯录—静态版

news2024/11/25 6:48:07

前言:

                        刚学完结构体和枚举,在网上找了个通讯录的项目,用来练手

                        目标:该通讯录可存储千人个人信息

                        包括:姓名,年龄,性别,电话,地址

                        实现功能:

                                1.添加联系人
                                2.删除联系人
                                3.查找联系人
                                4.修改联系人
                                5.打印通讯录
                                6.按姓名排序
                                0.退出通讯录

                       注:当前版本只是最初阶段,后续会持续更新

模块化(为了养成较好的编程习惯)

                将调试内容放入test.c中

                功能实现放入Contact.c中

                定义内容,头文件的引用放入到Contact.h中


准备工作:

1.创建联系人结构体               

typedef struct People//存储相关信息
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char telephone[TELEPHONE_MAX];
	char address[ADDRESS_MAX];
}People;

typedef struct Contact 
{
	People data[MAX];//存储自定义个数联系人的信息
	int sz;//相当于一个计数器
}Contact;

定义全局变量

//define定义常量以便后续进行修改时,过于繁琐,直接修改define内容即可
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define TELEPHONE_MAX 12
#define ADDRESS_MAX 30

定义枚举类型

        注:将switch,case后面的数字,替换成枚举类型,方便程序员修改,同时枚举类型,变量默认从上到下,从0开始依次递增

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

调试代码

 思想:   利用do-while()循环功能,input接收选择的数字,switch包含想要实现代码函数,case后面的数字替换成,枚举类型,以便后续修改时,程序员能更好的修改程序

void test()
{
	int input = 0;
	Contact con;
	Init_Contact(&con);//初始化通讯录,因为contact里面的变量未初始化,当前为随机值
	
	do 
	{
		menu();
		printf("请输入功能:>");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			printf("退出通讯录\n");
			return;
		 case ADD:
			 AddContact(&con);
			 break;
		 case DEL:
			 DelContact(&con);
			 break;
		 case SEARCH:
			 SearContact(&con);
			 break;
		 case MODIFY:
			 ModContact(&con);
			 break;
		 case PRINT:
			 PrintContact(&con);
			 break;
		 case SORT:
			 SortContact(&con);
			 break;
		 default:
			 printf("输入错误,暂无该选项\n");
			 break;
		}
	} while (input);
}

一、通讯录菜单

演示效果:

相关代码:

void menu()
{
	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");
}


功能实现

        1.添加联系人

            演示效果

                

相关代码 :     

该步骤用到函数assert,确保PC不为空指针,确保参数有效

 

void AddContact(Contact* pc)
{
	assert(pc);//断言,确保pc不为空指针
	if (pc->sz == MAX)
	{
		printf("通讯录已满无法存储,请即时更新后台程序");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s",(pc->data[pc->sz].name));
	printf("请输入年龄:>");
	scanf("%d",&(pc->data[pc->sz].age));
	printf("请输入性别:>");
	scanf("%s",(pc->data[pc->sz].sex));
	printf("请输入电话:>");
	scanf("%s",(pc->data[pc->sz].telephone));
	printf("请输入地址:>");
	scanf("%s",(pc->data[pc->sz].address));
	pc->sz++;
	printf("添加成功\n");
}

         2.删除联系人

            演示效果

相关代码: 

        代码思想:通过下标找到该联系人,直接将后面的存储信息,向前挪动一位

void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入想要删除的联系人:>");
	char name[NAME_MAX] = {0};
	scanf("%s",name);
	int pos = FindName(pc,name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	int j = 0;
	for (j=pos; j<pc->sz-1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;
	printf("删除成功");
}

3.查找联系人

        演示效果:
        

        注:实现该功能,我们需要确定,查找联系人的下标从而找到该联系人

int FindName(Contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i=0; i<pc->sz; i++)
	{
		if (strcmp(name,pc->data[i].name) == 0)
		{		
			return i;//利用strcmp函数,判断输入变量值是否与数组内容相匹配
                     //匹配返回当前变量下标
		}
	}
	if (strcmp(name, pc->data[i].name) != 0)
	{
		return -1;
	}

}

        相关代码:

void SearContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入想要查找的联系人:>");
	char name[NAME_MAX] = { 0 };
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址\n");
	printf("%-20s %-3d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].telephone, pc->data[pos].address);
	
}

        4.修改联系人

          演示效果:

                

 

          相关代码:

        代码思想:找到该联系人下标,数组中找到下标,在其基础上直接进行修改

void ModContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入想要修改的联系人:>");
	char name[NAME_MAX] = { 0 };
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	printf("请输入修改姓名:>");
	scanf("%s", (pc->data[pos].name));
	printf("请输入修改年龄:>");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入修改性别:>");
	scanf("%s", (pc->data[pos].sex));
	printf("请输入修改电话:>");
	scanf("%s", (pc->data[pos].telephone));
	printf("请输入修改地址:>");
	scanf("%s", (pc->data[pos].address));
	printf("修改成功\n");
}

5.打印通讯录

        演示效果:

                

        相关代码:

        代码思想:确定数组大小,定义一个变量,使其小于数组的大小,进行循环打印

void PrintContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址\n");
	int i = 0;
	for(i=0; i<pc->sz; i++)
	{
		printf("%-20s %-3d %-5s %-12s %-30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].telephone,pc->data[i].address);
	}
}

6.按姓名排序

        演示效果:

        相关代码:

void SortContact(Contact* pc)
{
	//按照姓名排序
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	int i = 0;
	int j = 0;
	for (i = 0; i < pc->sz - 1; i++)
	{
		for (j = 0; j < pc->sz - i - 1; j++)
		{
			if (strcmp(pc->data[j].name, (pc->data[j + 1]).name) > 0)
			{
				People tmp;
				tmp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
}

        


完整代码:

        Contact.h

#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
//define定义常量以便后续进行修改时,过于繁琐,直接修改define内容即可
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 10
#define TELEPHONE_MAX 12
#define ADDRESS_MAX 30
typedef struct People
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char telephone[TELEPHONE_MAX];
	char address[ADDRESS_MAX];
}People;

typedef struct Contact 
{
	People data[MAX];//存储联系人的信息
	int sz;//相当于一个计数器
}Contact;

enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	PRINT,
	SORT
};
//初始化通讯录
void Init_Contact(Contact* pc);

//增加联系人
void AddContact(Contact* pc);

//删除联系人
void DelContact(Contact* pc);

//修改联系人
void ModContact(Contact* pc);

//查找联系人
void SearContact(Contact* pc);

//排序通讯录
void SortContact(Contact* pc);

//打印通讯录
void PrintContact(Contact* pc);


Contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void Init_Contact(Contact* pc)
{
	pc->sz = 0;
	memset(pc->data,0,sizeof(pc->data));
}
void AddContact(Contact* pc)
{
	assert(pc);//断言,确保pc不为空指针
	if (pc->sz == MAX)
	{
		printf("通讯录已满无法存储,请即时更新后台程序");
		return;
	}
	printf("请输入姓名:>");
	scanf("%s",(pc->data[pc->sz].name));
	printf("请输入年龄:>");
	scanf("%d",&(pc->data[pc->sz].age));
	printf("请输入性别:>");
	scanf("%s",(pc->data[pc->sz].sex));
	printf("请输入电话:>");
	scanf("%s",(pc->data[pc->sz].telephone));
	printf("请输入地址:>");
	scanf("%s",(pc->data[pc->sz].address));
	pc->sz++;
	printf("添加成功\n");
}
void PrintContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址\n");
	int i = 0;
	for(i=0; i<pc->sz; i++)
	{
		printf("%-20s %-3d %-5s %-12s %-30s\n",pc->data[i].name,pc->data[i].age,pc->data[i].sex,pc->data[i].telephone,pc->data[i].address);
	}
}
//查找指定联系人的下标
int FindName(Contact* pc,char name[])
{
	assert(pc);
	int i = 0;
	for (i=0; i<pc->sz; i++)
	{
		if (strcmp(name,pc->data[i].name) == 0)
		{		
			return i;
		}
	}
	if (strcmp(name, pc->data[i].name) != 0)
	{
		return -1;
	}

}
void DelContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空,无法删除\n");
		return;
	}
	printf("请输入想要删除的联系人:>");
	char name[NAME_MAX] = {0};
	scanf("%s",name);
	int pos = FindName(pc,name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	int j = 0;
	for (j=pos; j<pc->sz-1; j++)
	{
		pc->data[j] = pc->data[j + 1];
	}
	pc->sz--;
	printf("删除成功");
}

void SearContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入想要查找的联系人:>");
	char name[NAME_MAX] = { 0 };
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	printf("%-20s %-3s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址\n");
	printf("%-20s %-3d %-5s %-12s %-30s\n", pc->data[pos].name, pc->data[pos].age, pc->data[pos].sex, pc->data[pos].telephone, pc->data[pos].address);
	
}
void ModContact(Contact* pc)
{
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	printf("请输入想要修改的联系人:>");
	char name[NAME_MAX] = { 0 };
	scanf("%s", name);
	int pos = FindName(pc, name);
	if (pos == -1)
	{
		printf("未查询到该联系人\n");
		return;
	}
	printf("请输入修改姓名:>");
	scanf("%s", (pc->data[pos].name));
	printf("请输入修改年龄:>");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入修改性别:>");
	scanf("%s", (pc->data[pos].sex));
	printf("请输入修改电话:>");
	scanf("%s", (pc->data[pos].telephone));
	printf("请输入修改地址:>");
	scanf("%s", (pc->data[pos].address));
	printf("修改成功\n");
}

void SortContact(Contact* pc)
{
	//按照姓名排序
	assert(pc);
	if (pc->sz == 0)
	{
		printf("通讯录为空\n");
		return;
	}
	int i = 0;
	int j = 0;
	for (i = 0; i < pc->sz - 1; i++)
	{
		for (j = 0; j < pc->sz - i - 1; j++)
		{
			if (strcmp(pc->data[j].name, (pc->data[j + 1]).name) > 0)
			{
				People tmp;
				tmp = pc->data[j];
				pc->data[j] = pc->data[j + 1];
				pc->data[j + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
}

test.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "Contact.h"
void menu()
{
	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");
}
void test()
{
	int input = 0;
	Contact con;
	Init_Contact(&con);//初始化通讯录,因为contact里面的变量未初始化,当前为随机值
	
	do 
	{
		menu();
		printf("请输入功能:>");
		scanf("%d", &input);
		switch (input)
		{
		case EXIT:
			printf("退出通讯录\n");
			return;
		 case ADD:
			 AddContact(&con);
			 break;
		 case DEL:
			 DelContact(&con);
			 break;
		 case SEARCH:
			 SearContact(&con);
			 break;
		 case MODIFY:
			 ModContact(&con);
			 break;
		 case PRINT:
			 PrintContact(&con);
			 break;
		 case SORT:
			 SortContact(&con);
			 break;
		 default:
			 printf("输入错误,暂无该选项\n");
			 break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

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

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

相关文章

Web 安全漏洞之 XSS 攻击

什么是 XSS 攻击 XSS&#xff08;Cross-Site Scripting&#xff09;又称跨站脚本&#xff0c;XSS的重点不在于跨站点&#xff0c;而是在于脚本的执行。XSS是一种经常出现在 Web 应用程序中的计算机安全漏洞&#xff0c;是由于 Web 应用程序对用户的输入过滤不足而产生的。 常…

MyBatis -- 多表查询

MyBatis -- 多表查询一、准备工作二、多表查询属性名与字段名不匹配一、准备工作 博客系统场景。 创建库、表&#xff1a; -- 创建数据库 drop database if exists mycnblog; create database mycnblog DEFAULT CHARACTER SET utf8mb4;-- 使用数据数据 use mycnblog;-- 创建…

小程序样式和组件基础

小程序样式和组件基础小程序样式样式wxss简介响应式单位rpx其它css单位支持的单位内置组件简介image组件-基础组件介绍常用属性示例image组件-懒加载与基础库版本用法swiper组件组件介绍常用属性示例navigator组件-基础组件介绍常用属性示例navigator组件-页面栈页面栈返回按钮…

常用windows自带程序对应的命令

敲winr键&#xff0c;调出 运行 框&#xff1b; 输入命令回车&#xff0c;打开对应程序&#xff1b; 输入cmd&#xff0c;调出命令行窗口&#xff1b; gpedit&#xff0c;组策略编辑器&#xff0c; 有的电脑没有组策略编辑器&#xff1b; 资源管理器&#xff1b; dvdplay&…

【BP靶场portswigger-客户端15】基于DOM的漏洞-7个实验(全)

前言&#xff1a; 介绍&#xff1a; 博主&#xff1a;网络安全领域狂热爱好者&#xff08;承诺在CSDN永久无偿分享文章&#xff09;。 殊荣&#xff1a;CSDN网络安全领域优质创作者&#xff0c;2022年双十一业务安全保卫战-某厂第一名&#xff0c;某厂特邀数字业务安全研究员&…

使用PyTorch构建GAN生成对抗网络源码(详细步骤讲解+注释版)02 人脸识别 上

文章目录1 数据集描述2 GPU设置3 设置Dataset类4 设置辨别器类5 辅助函数与辅助类1 数据集描述 此项目使用的是著名的celebA&#xff08;CelebFaces Attribute&#xff09;数据集。其包含10,177个名人身份的202,599张人脸图片&#xff0c;每张图片都做好了特征标记&#xff0c…

【数据结构】顺序表的原理及实现

1.什么是顺序表 顺序表是用一段物理地址连续的存储单元进行存储元素的线性结构&#xff0c;通常是以数组进行存储。通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。 2.顺序表的实现 判断顺序表是否为空表public boolean isEmpty()判断顺序表是否满publi…

复旦MBA海外短期课程 | 善用ESG金融,共创可持续未来

2022年&#xff0c;世界在颠簸中向前迈进&#xff1a;全球气候变化、能源危机、大国博弈……在这样的背景下&#xff0c;近年来备受瞩目的ESG价值、“双碳”目标、可持续发展、责任投资等话题愈发成为焦点。今年复旦MBA培养体系全面升级之际&#xff0c;在新增的“未来发展模块…

Pandas CSV 文件

Pandas CSV 文件CSV&#xff08;Comma-Separated Values&#xff0c;逗号分隔值&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。CSV 是一种通用的、相对…

【沐风老师】3dMax一键生成中央空调排风口插件使用教程

3dMax一键创建中央空调排风口插件&#xff0c;快捷生成矩形或菱形两种形状的排风口。 【版本要求】 不确定。3dmax2020环境测试可用&#xff0c;其他版本自行测试&#xff0c;欢迎反馈测试结果。 【安装方法】 方法一&#xff1a;拖动插件文件到3dMax窗口打开。 方法二&#x…

ESP32相关知识点

1.vs code代码回退到上一步: 方法1:在Windows中可以使用快捷键“Alt←”实现 方法2:利用vs code界面操作&#xff0c;Go-Back 2.设置vs code下ESP-IDF Monitor Device的波特率。 步骤Manage-New Code update available------Command Palette 弹出对话框 搜索或选择:ESP-IDF:SD…

基于Androidstudio的打车拼车app

需求信息&#xff1a; 客户端&#xff1a; 1&#xff1a;注册和登录:用户信息录入与登录。 2&#xff1a;修改密码:用户忘记密码可在此处找回。 3&#xff1a;地图功能:提供城市地图&#xff0c;能被自由移动、放大和缩小。 4&#xff1a;自身定位:获取用户位置信息&#xff0c…

STM-PWM采集

输入捕获分为两种方式进行捕获 1、pwm输入捕获:精度高&#xff0c;每个定时器只能采集一个pwm&#xff0c;且只能使用通道1、通道2。 2、通用输入捕获&#xff1a;相对比较精确&#xff0c;每个定时器可以采集多个pwm&#xff0c; 1、pwm输入捕获使用教程如下&#xff1a; 参…

Vue 快速入门(一)

1、介绍 Vue(读音/vju/&#xff0c;类似view)&#xff0c;是中国的大神尤雨溪开发的&#xff0c;为数不多的国人开发的世界顶级开源软件。是一套用于构建用户界面的渐进式框架&#xff0c;Vue 被设计为可以自底向上逐层应用。MVVM响应式编程模型&#xff0c;避免直接操作DOM&am…

虹科分享 | HPC调度解决方案:HK-Adaptive在数字卫星图像领域的应用

2011年3月11日&#xff0c;日本海岸附近发生了9.0级地震。这次地震引发了强大的海啸&#xff0c;并向内陆传播了6英里&#xff0c;不仅使地球的轴心偏移了大约10到25厘米&#xff0c;还导致福岛核电站发生核紧急情况。 为了减少这场灾害的损失&#xff0c;不同国家的不同组织以…

浅谈虚拟电厂与企业微电网数字化建设

安科瑞 华楠摘要&#xff1a;2023年1月8日&#xff0c;微信公众号鱼眼看电改(作者俞庆)发表了文章《虚拟电厂与负荷侧数字化》&#xff0c;原文如下&#xff1a;“虚拟电厂是电力数字化的一个应用方向&#xff0c;准确的说&#xff0c;是负荷侧数字化的发展方向。所以负荷侧数字…

NetSuite Classifications的注意事项

Classifications&#xff0c;我们将之称为“分析维度”吧&#xff0c;这样更能体现其真正的用途。在NetSuite中标准的分析维度是“LDC&#xff08;Location、Department、Class&#xff09;”&#xff0c;这是NetSuite的特色。有些注意事项我们今天分享下。 1. LDC的用途区别 …

Django REST framework--Swagger API文档生成器

Django REST framework--Swagger API文档生成器swagger在线接口文档drf-yasg安装与配置安装drf-yasg配置drf-yasg互动模式文档模式定制化用法&#xff08;viewset模式&#xff09;修饰视图装饰器api_view修饰视图集swagger在线接口文档 目前为止&#xff0c;接口开发到了一定的…

Spring AOP【统一异常处理与统一数据格式封装】

Spring AOP【统一异常处理与统一格式封装】&#x1f34e;一.统一异常处理&#x1f352;1.1 实现一个异常方法&#x1f352;1.2 统一处理异常代码的实现&#x1f352;1.3 统一处理所有异常&#x1f34e;二.统一格式封装&#x1f352;2.1 实现一个返回数据方法&#x1f352;2.2 统…

回收租赁商城系统功能拆解09讲-会员管理

回收租赁系统适用于物品回收、物品租赁、二手买卖交易等三大场景。 可以快速帮助企业搭建类似闲鱼回收/爱回收/爱租机/人人租等回收租赁商城。 回收租赁系统支持智能评估回收价格&#xff0c;后台调整最终回收价&#xff0c;用户同意回收后系统即刻放款&#xff0c;用户微信零…