C语言进阶|通讯录的实现

基于动态顺序表实现通讯录

C语言基础要求:结构体、动态内存管理、顺序表、文件操作
1、功能要求

  1. 至少能够存储100个人的通讯信息
  2. 能够保存用户信息:名字、性别、年龄、电话、地址等
  3. 增加联系人信息
  4. 删除指定联系人
  5. 查找制定联系人
  6. 修改指定联系人
  7. 显示联系人信息

2、代码实现

【思考1】用静态顺序表和动态顺序表分别如何实现
【思考2】如何保证程序结束后,历史通讯录信息不会丢失

//contact.h
#define NAME_MAX 11
#define TEL_MAX 13
#define SEX_MAX 5
#define ADDR_MAX 14
//通讯录包含的类型
typedef struct
{
	char name[NAME_MAX];
	int age;
	char tel[TEL_MAX];
	char sex[SEX_MAX];
	char addr[ADDR_MAX];
}PersonInfo;
//前置声明
struct Seqlist;
typedef struct Seqlist CT;
//初始化
void CTInit(CT* ct);
//销毁
void CTDestroy(CT* ct);
//查看
void CTCheck(CT* ct);
//增加
void CTAdd(CT* ct);
//删除
void CTDel(CT* ct);
//查找
void CTFind(CT* ct);
//修改
void CTVice(CT* ct);
//contact.c
//查找函数
int CTFind1(CT* ct)
{
	char tmp[NAME_MAX] = { 0 };
	scanf("%s", tmp);
	for (int i = 0; i < ct->size; i++)
	{
		if (!strcmp(tmp, ct->sqlist->name))
		{
			return i;
		}
	}
	return -1;

}
//赋值函数
void CTAss(SLTYPE* a, SLTYPE* b)
{
	for (int i = 0; i < NAME_MAX; i++)
		a->name[i] = b->name[i];
	a->age = b->age;
	for (int i = 0; i < TEL_MAX; i++)
		a->tel[i] = b->tel[i];
	for (int i = 0; i < SEX_MAX; i++)
		a->sex[i] = b->sex[i];
	for (int i = 0; i < ADDR_MAX; i++)
		a->addr[i] = b->addr[i];
}
//初始化
void CTInit(CT* ct)
{
	ct->size = 0;
	ct->capacity = 0;
	ct->sqlist = NULL;
}
//销毁
void CTDestroy(CT* ct)
{
	free(ct->sqlist);
	ct->sqlist = NULL;
	ct->size = ct->capacity = 0;
}
//查看
void CTCheck(CT* ct)
{
	printf("%-11s%-8s%-13s%-8s%-14s\n", "姓名", "年龄", "电话", "性别", "住址");
	for (int i = 0; i < ct->size; i++)
	{
		printf("%-11s%-8d%-13s%-8s%-14s\n", ct->sqlist[i].name, ct->sqlist[i].age, ct->sqlist[i].tel, ct->sqlist[i].sex, ct->sqlist[i].addr);
	}
}
//增加
void CTAdd(CT* ct)
{
	//先判断是否要扩容
	if (ct->size == ct->capacity)
	{
		int newcapacity = ct->capacity == 0 ? 4 : 2 * ct->capacity;
		SLTYPE* tmp = (SLTYPE*)realloc(ct->sqlist, newcapacity * sizeof(SLTYPE));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(1);
		}
		ct->sqlist = tmp;
	}
	printf("请输入联系人的姓名:\n");
	scanf("%s", (ct->sqlist+ct->size)->name);
	printf("请输入联系人的年龄:\n");
	scanf("%d", &(ct->sqlist+ ct->size)->age);
	printf("请输入联系人的电话:\n");
	scanf("%s", (ct->sqlist+ ct->size)->tel);
	printf("请输入联系人的性别:\n");
	scanf("%s", (ct->sqlist+ ct->size)->sex);
	printf("请输入联系人的地址:\n");
	scanf("%s", (ct->sqlist+ ct->size)->addr);
	ct->size++;
	CTSort(ct);
}
//删除
void CTDel(CT* ct)
{
	printf("请输入要删除的联系人:\n");
	int pos = CTFind1(ct);
	if (pos == -1)
	{
		printf("找不到此联系人,请检查是否输入错误。\n");
		return;
	}
	for (int i = pos; i < ct->size; i++)
	{
		CTAss(ct->sqlist + i, ct->sqlist + i + 1);
	}
	ct->size--;
	printf("删除成功!\n");
}
//查找
void CTFind(CT* ct)
{
	printf("请输入想要查找的联系人:\n");
	int pos = CTFind1(ct);
	printf("%-11s%-8s%-13s%-8s%-14s\n", "姓名", "年龄", "电话", "性别", "住址");
	printf("%-11s%-8d%-13s%-8s%-14s\n", ct->sqlist[pos].name, ct->sqlist[pos].age, ct->sqlist[pos].tel, ct->sqlist[pos].sex, ct->sqlist[pos].addr);
}
//修改
void CTVice(CT* ct)
{
	printf("请输入要修改的联系人:\n");
	int pos = CTFind1(ct);
	if (pos == -1)
	{
		printf("找不到此联系人,请检查是否输入错误。\n");
		return;
	}
	char type[8] = { 0 };
	printf("请输入要修改的数据类型:\n");
	scanf("%s", type);
	if (!strcmp(type, "姓名"))
	{
		printf("请输入要修改的姓名:\n");
		char tmp_name[NAME_MAX] = { 0 };
		scanf("%s", tmp_name);
		for (int i = 0; i < NAME_MAX; i++)
			(ct->sqlist+pos)->name[i] = tmp_name[i];
		CTSort(ct);
	}
	else if (!strcmp(type, "年龄"))
	{
		printf("请输入要修改的年龄:\n");
		int tmp_age = 0;
		scanf("%d", &tmp_age);
		(ct->sqlist+pos)->age = tmp_age;
	}
	else if (!strcmp(type, "电话"))
	{
		printf("请输入要修改的电话:\n");
		char tmp_tel[TEL_MAX] = { 0 };
		scanf("%s", &tmp_tel);
		for (int i = 0; i < TEL_MAX; i++)
			(ct->sqlist+pos)->tel[i] = tmp_tel[i];
	}
	else if (!strcmp(type, "性别"))
	{
		printf("请输入要修改的性别:\n");
		char tmp_sex[SEX_MAX] = { 0 };
		scanf("%s", tmp_sex);
		for (int i = 0; i < SEX_MAX; i++)
			(ct->sqlist+pos)->sex[i] = tmp_sex[i];
	}
	else if (!strcmp(type, "住址"))
	{
		printf("请输入要修改的住址:\n");
		char tmp_addr[ADDR_MAX] = { 0 };
		scanf("%s", tmp_addr);
	}
	else
	{
		printf("输入错误\n");
	}
}
//test.c
void menu()
{
	printf("**************************************\n");
	printf("*****1.添加联系人    2.删除联系人*****\n");
	printf("*****3.查找联系人    4.修改联系人*****\n");
	printf("*****5.查看联系人    0.  退  出  *****\n");
	printf("**************************************\n");
}

int main()
{
	CT contect1;
	CTInit(&contect1);
	int choice = 1;
	do
	{
		menu();
		printf("请输入你要做的选项:\n");
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:CTAdd(&contect1);
			break;
		case 2:CTDel(&contect1);
			break;
		case 3:CTFind(&contect1);
			break;
		case 4:CTVice(&contect1);
			break;
		case 5:CTCheck(&contect1);
			break;
		case 0:CTDestroy(&contect1);
			break;
		default:printf("输入错误,请重新输入:\n");
			break;
		}
	} while (choice);


	return 0;
}

顺序表的问题及思考

  1. 中间/头部的插入删除,时间复杂度为O(N)。
  2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。
  3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

思考:如何解决以上问题呢?

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Springboot的社区疫情返乡管控系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的社区疫情返乡管控系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系…

OpenHarmony 上传和下载(API 10)教程~

介绍 本示例使用ohos.request接口创建上传和下载任务&#xff0c;实现上传、下载功能&#xff0c;hfs作为服务器&#xff0c;实现了文件的上传和下载和任务的查询功能。 效果预览 使用说明 1.本示例功能需要先配置服务器环境后使用&#xff0c;具体配置见上传下载服务配置。…

中颖51芯片学习7. printf重定向到串口与自定义日志输出函数

中颖51芯片学习7. printf重定向到串口与自定义日志输出函数 一、 printf 重定向1. 概念2. 实现方式3. C51 中printf数值格式化 二、日志函数1. 实现方案分析2. 代码&#xff08;1&#xff09;log_utils.h&#xff08;2&#xff09;main.c 3. 通过预定义宏实现日志分级输出&…

汇编语言88888

汇编语言安装指南 第一步&#xff1a;在github上下载汇编语言的安装包 网址&#xff1a;GitHub - HaiPenglai/bilibili_assembly: B站-汇编语言-pdf、代码、环境等资料B站-汇编语言-pdf、代码、环境等资料. Contribute to HaiPenglai/bilibili_assembly development by creat…

Flyweight 享元

意图 运用共享技术有效地支持大量细粒度的对象。 结构 其中 Flyweight描述一个接口&#xff0c;通过这个接口Flyweight可以接受并作用于外部状态。ConcreteFlyweight实现Flyweight接口&#xff0c;并作为内部状态&#xff08;如果有&#xff09;增加存储空间。ConcreteFlywe…

数字阅览室解决方案

一、方案概述 “数字阅览室”概念一经提出&#xff0c;就得到了广泛的关注&#xff0c;纷纷组织力量进行探讨、研究和开发&#xff0c;进行各种模型的试验。随着数字地球概念、技术、应用领域的发展&#xff0c;数字阅览室已成为数字地球家庭的成员&#xff0c;为信息高速公路…

vue3:树的默认勾选和全选、取消全选

实现的功能&#xff0c;上面有个选择框&#xff0c;当选中全部时&#xff0c;下方树被全选 代码&#xff1a; <template><div><el-select v-model"selectAll" style"margin-bottom: 10px;" change"handleSelectAllChange">&…

运行transformers报错check_min_version(“4.40.0.dev0“)

在huggingface &#xff08;transformers项目地址&#xff09;下载transformers的项目 并 python /transformers/examples/pytorch/language-modeling/run_clm.py 时报错 报错如下&#xff1a; 安装的 transformers 版本不对&#xff0c;这里安装了 4.39.3&#xff0c;实际想…

网站备案期间怎么关闭首页显示无法访问-文章及其它页面正常访问

自从做了开发者之后才发现每个人博主的需求都是不同的&#xff0c;的的确确颠覆了我的观点&#xff0c;无论是页面布局还是SEO相关的设置&#xff0c;可能是因为站点属性不同所以需求不同&#xff0c;慢慢的就会在主题加入一些自定接口来满足不同人的需求&#xff0c;有人需要P…

双链表的实现

我们知道链表其实有很多种&#xff0c;什么带头&#xff0c;什么双向啊&#xff0c;我们今天来介绍双向带头循环链表&#xff0c;了解了这个其他种类的链表就很简单了。冲冲冲&#xff01;&#xff01;&#xff01; 链表的简单分类 链表有很多种&#xff0c;什么带头循环链表&…

【c基础】文件操作

1.fopen和fclose函数 函数原型 FILE *fopen(const char *path, const char *mode); 参数解释&#xff1a; 返回值&#xff1a;fopen打开成功&#xff0c;则返回有效file的有效地址&#xff0c;失败返回NULL。path是文件路径&#xff0c;可以相对路径&#xff0c;可以绝对路径…

“手撕“三大特性之一的<继承>(上)

目录 一、为什么需要继承 二、什么是继承 三、继承怎么写 四、成员的访问 1.父类与子类的成员变量不同名 2.父类与子类的成员变量同名 3.父类与子类的成员方法不同名 4.父类与子类的成员方法同名 五、super关键字 一、为什么需要继承 先让我们看一段Java代码&#…

Unity地形关联出错的解决办法以及地形深度拷贝

问题 最近发现unity地形系统的一个bug&#xff0c;导入的场景地形数据关联错乱了&#xff0c;关联到别的场景的地形数据了&#xff0c;meta替换了也没用&#xff0c;不清楚它具体是怎么关联的。 看下面的案例&#xff1a; 可以看到正常这个场景的地形数据应该关联的是Scene_E…

力扣HOT100 - 142. 环形链表 II

解题思路&#xff1a; public class Solution {public ListNode detectCycle(ListNode head) {Set<ListNode> set new HashSet<>();while (head ! null) {if (!set.add(head)) {return head;}head head.next;}return null;} }

文心一言 VS 讯飞星火 VS chatgpt (241)-- 算法导论17.3 7题

七、为动态整数多重集 S (允许包含重复值)设计一种数据结构&#xff0c;支持如下两个操作&#xff1a;① INSERT(S,x) 将 x 插入 S 中&#xff1b;② DELETE-LARGER-HALF(S) 将最大的 ⌈|S|/2⌉ 个元素从S中删除。解释如何实现这种数据结构&#xff0c;使得任意 m 个 INSERT 和…

Linux的firewalld防火墙

介绍firewalld&#xff1a; ①、firewalld&#xff08;Dynamic Firewall Manager of Linux systems&#xff0c;Linux系统的动态防火墙管理器&#xff09;服务是默认的防火墙配置管理工具&#xff0c;它拥有基于CLI&#xff08;命令行界面&#xff09;和基于GUI&#xff08;图…

Web Tours系统使用说明书

1.系统简介 产品名称&#xff1a;LoadRunner的Web Tours系统 产品功能&#xff1a;注册和登录用户信息、订票办理、退片办理、查询已定票信息、退出系统 系统默认用户&#xff1a;用户名jojo 密码&#xff1a;bean 2. 功能简介 2.1 注册用户信息 点击 sign up now&#xff…

(自学用)正演理论

基于波动方程如何解决数值频散问题——快速正演方法 NAD方法&#xff1a; 怎样离散/逼近高阶偏导数&#xff08;如何采样&#xff09;&#xff1a; 传统方法是用某一点及其周围点的函数f的线性组合来逼近导数。只有函数值&#xff0c;要想提高精度&#xff0c;压制数值频散就必…

(C语言)fscanf与fprintf函数详解

目录 1 fprintf详解 1.1 向文件流中输入数据 1.2 向标准输入流写数据 2. fscanf函数详解 2.1 从文件中读取格式化数据 2.2 从标准输入流中读取格式化数据 1 fprintf详解 头文件&#xff1a;stdio.h 该函数和printf的参数特别像&#xff0c;只是多了一个参数stream&#…

Unity类银河恶魔城学习记录13-5,6 p146 Delete save file,p147 Encryption of saved data源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili FileDataHandler.cs using System; using System.IO; using UnityEngine; p…
最新文章