数据结构——顺序表实现通讯录

目录

前言

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

二、代码具体实现

2.1 初始化通讯录

2.2 添加通讯录数据

2.3 展示通讯录

2.4 按名字来查找通讯录信息

2.5 删除通讯录的数据

2.6 查找通讯录的数据

2.7 修改通讯录的数据

2.8 销毁通讯录

上传通讯录数据

写入通讯录数据

三、完整代码

总结


前言

之前我们讲了数据结构中的顺序表:数据结构——顺序表

今天我们基于顺序表来实现通讯录,实现添加,删除,查找,修改,展示的功能。通过结构体来存储通讯录的数据,通过菜单进行交互,最后进行上传到文件中保存,这就是我们通讯录的功能实现。


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

C语⾔基础要求:结构体、动态内存管理、顺序表、文件操作
1、功能要求
1)至少能够存储100个人的通讯信息
2)能够保存用户信息:名字、性别、年龄、电话、地址等
3)增加联系⼈信息
4)删除指定联系⼈
5)查找制定联系⼈
6)修改指定联系⼈
7)显示联系⼈信息

以上就是通讯录的功能要求,现在我们就来实现代码。

二、代码具体实现

实现我们是基于顺序表代码实现的,所以我们需要顺序表的头文件

//Seqlist.h#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.h>
#include"contact.h"typedef PeoInfo SLDataType;//定义新的数据类型typedef struct Seqlist {SLDataType* arr;int size;		//有效数据个数int	capacity;  //数组容量
} SL;//初始化和销毁
void SLInit(SL* ps);
void SLDestroy(SL* ps);
void SLPrint(SL* ps);//扩容
void SLCheckCapacity(SL* ps);
//头部插入
void SLPushFront(SL* ps, SLDataType x);
//尾部插入
void SLPushBack(SL* ps, SLDataType x);
//头部删除
void SLPopFront(SL* ps);
//尾部删除
void SLPopBack(SL* ps);
//插入任意位置
void SLInsert(SL* ps, int pos, SLDataType x);
//删除任意位置
void SLErase(SL* ps, int pos);
//查找元素
int SLFind(SL* ps, SLDataType x);

跟顺序表一样,只不过顺序表内容不是整型内容,而是我们定义的结构体内容(联系人信息)

//contact.h#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];//姓名char sex[SEX_MAX];//性别int age;//年龄char tel[TEL_MAX];//电话char addr[ADDR_MAX];//住址
}PeoInfo;//结构体类型

现在我们就要进行通讯录的功能实现了

主要接口:

//contact.h//前置类型声明
struct Seqlist;//调用必须先声明typedef struct Seqlist contact;//给顺序表重命名为contact//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);//读取本地通讯录
void LoadContact(contact* con);//上传通讯录数据到文件
void SaveContact(contact* con);

2.1 初始化通讯录

//初始化通讯录
void InitContact(contact* con) {SLInit(con);
}

调用顺序表的初始化函数SLInit函数,即可完成对通讯录的初始化。

2.2 添加通讯录数据

void AddContact(contact* con) {PeoInfo info;  //定义一个结构体类型为 通讯录数据printf("请输入姓名:\n");scanf("%s", &info.name);printf("请输入性别:\n");scanf("%s", &info.sex);printf("请输年龄:\n");scanf("%d", &info.age);printf("请输入电话:\n");scanf("%s", &info.tel);printf("请输入住址:\n");scanf("%s", &info.addr);printf("添加成功\n");SLPushBack(con, info);//调用顺序表尾插
}

我们要添加联系人,就要添加一个我们定义的PeoInfo结构体(联系人信息)的结构体变量,然后往里面添加姓名,性别,年龄,电话,住址信息,最后插入通讯录。

2.3 展示通讯录

我们添加后查看通讯录里面的有哪些联系人信息。

void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");for (int i = 0; i < con->size; i++) {//打印个数小于有效数据个数printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[i].name, con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}

2.4 按名字来查找通讯录信息

我们进行删除,修改,查找操作之前我们要找到操作的对象,我们以名字来查找。

int FindByName(contact* con, char name[]) {for (int i = 0; i < con->size; i++) {if (strcmp(con->arr[i].name, name) == 0) {return i;//找到返回下标}}return -1;//没找到返回-1
}

2.5 删除通讯录的数据

void DelContact(contact* con) {char name[NAME_MAX];//定义数组为删除人的名字printf("请输入删除人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//进行查找if (pos < 0) {printf("没有找到删除的人名,删除失败\n");}else {SLErase(con, pos);printf("删除成功!\n");}}

我们调用顺序表删除任意位置的元素SLErase函数,进行删除通讯录里面的数据。

2.6 查找通讯录的数据

//查找通讯录的数据
void FindContact(contact* con) {char name[NAME_MAX];//定义数组为查找人的姓名printf("请输入查找人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//查找是否存在if (pos < 0) {printf("没有找到,查找失败\n");}else {printf("找到了:\n");//找到了打印信息printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}
}

2.7 修改通讯录的数据

void ModifyContact(contact* con) {char name[NAME_MAX];//定义数组为修改人的姓名printf("请输入姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//查找if (pos < 0) {printf("没有找到,修改失败\n");}else {printf("请输入修改人的姓名:\n");scanf("%s", &con->arr[pos].name);printf("请输入修改人的性别:\n");scanf("%s", &con->arr[pos].sex);printf("请输修改人的年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改人的电话:\n");scanf("%s", &con->arr[pos].tel);printf("请输入修改人的住址:\n");scanf("%s", &con->arr[pos].addr);printf("修改成功\n");}
}

2.8 销毁通讯录

//销毁通讯录数据
void DestroyContact(contact* con) {SLDestroy(con);
}

我们调用顺序表的销毁函数SLDestroy进行销毁通讯录的数据

但是我们要保留通讯录的数据,那么我们就可以在销毁前写入文件中:

上传通讯录数据

void SaveContact(contact* con) {FILE* pf = fopen("contact.txt", "wb");//文件指针if (pf == NULL) {perror("fopen error!\n");return;}//将通讯录数据写⼊⽂件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);//通过fwrite写入文件}printf("通讯录数据保存成功!\n");
}

在下次使用时初始化中

写入通讯录数据

void LoadContact(contact* con) {FILE* pf = fopen("contact.txt", "rb");if (pf == NULL) {perror("fopen error!\n");return;}//循环读取⽂件数据PeoInfo info;//定义info为通讯录数据while (fread(&info, sizeof(PeoInfo), 1, pf))//读info类型数据不为空{SLPushBack(con, info);//尾插info数据}printf("历史数据导入通讯录成功!\n");
}

三、完整代码

通讯录功能头文件

//contact.h
#pragma once#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;//前置类型
struct Seqlist;typedef struct Seqlist contact;//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);//读取本地通讯录
void LoadContact(contact* con);//上传通讯录数据到文件
void SaveContact(contact* con);

通讯录功能具体实现

//contact.c
#include"Seqlist.h"
#include"contact.h"//初始化通讯录
void InitContact(contact* con) {SLInit(con);LoadContact(con);
}
//添加通讯录数据
void AddContact(contact* con) {PeoInfo info;printf("请输入姓名:\n");scanf("%s", &info.name);printf("请输入性别:\n");scanf("%s", &info.sex);printf("请输年龄:\n");scanf("%d", &info.age);printf("请输入电话:\n");scanf("%s", &info.tel);printf("请输入住址:\n");scanf("%s", &info.addr);printf("添加成功\n");SLPushBack(con, info);
}
//展⽰通讯录
void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");for (int i = 0; i < con->size; i++) {printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[i].name, con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
//按名字来查找
int FindByName(contact* con, char name[]) {for (int i = 0; i < con->size; i++) {if (strcmp(con->arr[i].name, name) == 0) {return i;}}return -1;
}
//删除通讯录的数据
void DelContact(contact* con) {char name[NAME_MAX];printf("请输入删除人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到删除的人名,删除失败\n");}else {SLErase(con, pos);printf("删除成功!\n");}}
//查找通讯录的数据
void FindContact(contact* con) {char name[NAME_MAX];printf("请输入查找人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到,查找失败\n");}else {printf("找到了:\n");printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}
}
//修改通讯录数据
void ModifyContact(contact* con) {char name[NAME_MAX];printf("请输入姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到,修改失败\n");}else {printf("请输入修改人的姓名:\n");scanf("%s", &con->arr[pos].name);printf("请输入修改人的性别:\n");scanf("%s", &con->arr[pos].sex);printf("请输修改人的年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改人的电话:\n");scanf("%s", &con->arr[pos].tel);printf("请输入修改人的住址:\n");scanf("%s", &con->arr[pos].addr);printf("修改成功\n");}
}//销毁通讯录数据
void DestroyContact(contact* con) {SaveContact(con);SLDestroy(con);
}//读取本地通讯录
void LoadContact(contact* con) {FILE* pf = fopen("contact.txt", "rb");if (pf == NULL) {perror("fopen error!\n");return;}//循环读取⽂件数据PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){SLPushBack(con, info);}printf("历史数据导入通讯录成功!\n");
}//上传通讯录数据到文件
void SaveContact(contact* con) {FILE* pf = fopen("contact.txt", "wb");if (pf == NULL) {perror("fopen error!\n");return;}//将通讯录数据写⼊⽂件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);}printf("通讯录数据保存成功!\n");
}

通讯录主函数

contactest.ccontactest.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
#include"Seqlist.h"void num() {printf("*************************************\n");printf("**** 1. 添加联系人  2. 删除联系人****\n");printf("**** 3. 查找联系人  4. 修改联系人****\n");printf("**** 5. 展示通讯录  0.   退出    ****\n");printf("*************************************\n");
}int main() {int inputt = 0;contact con;InitContact(&con);do {num();printf("请输入操作:\n");scanf("%d", &inputt);switch (inputt){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3: FindContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;case 0:printf("通讯录退出中--\n");break;}} while (inputt);DestroyContact(&con);return 0;
}

还要顺序表的代码,这里就不在赘述。


总结

上述文章讲了基于顺序表为主要框架来实现通讯录的功能,希望对你有所帮助。

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

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

相关文章

基础之重蹈覆辙

MESI缓存一致性协议 前&#x1f33d;&#xff1a; 高速缓存底层数据结构&#xff1a;拉链散列表的结构 bucket - cache entry - tag主内存地址 cache line缓存数据 flag缓存行状态 cache line64字节 有效引用主内存地址&#xff0c;连续的相邻的数据结构 读取特别快 处理器…

关于Tomcat双击startup.bat 闪退的解决⽅法

详解Tomcat双击startup.bat 闪退的解决⽅法 作为⼀个刚学习Tomcat的程序猿来说&#xff0c;这是会经常出现的错误。 1.环境变量问题 1.1 ⾸先需要确认java环境是否配置正确&#xff0c;jdk是否安装正确 winR打开cmd&#xff0c;输⼊java 或者 javac 出现下图所⽰就说明jdk配置正…

AI与技术美术(TechArt)

AI技术与TA 人工智能&#xff08;AI&#xff09;技术在技术美术&#xff08;TechArt&#xff09;领域的应用&#xff0c;为创业者开辟了一片新的天地。技术美术作为一个跨学科领域&#xff0c;融合了传统美术和现代技术&#xff0c;特别是AI技术&#xff0c;以创造新型的艺术表…

spark-hive连接操作流程、踩坑及解决方法

文章目录 1 简介2 版本匹配3 spark hive支持版本源码编译3.1 spark-src下载3.2 maven换源3.3 spark编译 4 hive 安装与mysql-metastore配置4.1 mysql下载安装4.1.1 为mysql设置系统环境变量4.1.2 初次登陆更改root身份密码4.1.3 安装后直接更改密码 4.2 hive初始化4.2.1 编写hi…

【leetcode面试经典150题】10.跳跃游戏 II(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

pycharm pyspark连接虚拟机的hive表 读取数据

方法&#xff1a; hive配置hiveserver2和metastore url <!-- 指定hiveserver2连接的host --> <property><name>hive.server2.thrift.bind.host</name><value>hadoop111</value> </property><!-- 指定hiveserver2连接的端口号 -…

langchain + azure chatgpt组合配置并运行

首先默认你已经有了azure的账号。 最重要的是选择gpt-35-turbo-instruct模型、api_version&#xff1a;2023-05-15&#xff0c;就这两个参数谷歌我尝试了很久才成功。 我们打开https://portal.azure.com/#home&#xff0c;点击更多服务&#xff1a; 我们点击Azure OpenAI&#…

华为ensp中ospf多区域管理 原理及配置命令(详解)

作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; ————前言———— OSPF 多区域的主要作用是缩小链路状态数据库和路由表的规模&#xff0c;减少路由更新的频率&#xff0c;提高网络的可扩展性&#xff0c;实现路由过滤和路由汇总&#xff0…

0.k8s简介

目录 k8s是什么 k8s不是什么 云原生 微服务 整体式架构与微服务架构 微服务的特性 微服务的优势 k8s是什么 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快…

A First Course in the Finite Element Method【Daryl L.】|PDF电子书

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

zdpcss_transparent_animation_login:使用纯HTML+CSS+JS开发支持设置主题和带动画的科技风登录界面

废话不多说&#xff0c;先上图&#xff0c;有图有真相&#xff1a; 在左下角有一排颜色&#xff0c;点击可以设置主题色&#xff1a; 比如&#xff0c;我这里点击了橙色&#xff0c;登录界面就变成了如下样子&#xff1a; 另外&#xff0c;在输入账号和密码的时候&#x…

使用 ChatGPT 创建在线课程:一步一步指南与提示模板

原文&#xff1a;Creating Online Courses with ChatGPT 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 谢谢 作为对你支持的感谢&#xff0c;随意定制本书中列出的任何提示&#xff0c;并将其作为你自己的重新销售。是的&#xff0c;对你免费。 它们都结构良好且用…

蓝桥杯—DS1302

目录 1.管脚 2.时序&官方提供的读写函数 3.如何使用读写函数 4.如何在数码管中显示在DS1302中读取出的数据&#xff1f; 1.管脚 2.时序&官方提供的读写函数 /* # DS1302代码片段说明1. 本文件夹中提供的驱动代码供参赛选手完成程序设计参考。2. 参赛选手可以自行…

英语写作中“概念”concept 、notion、idea的用法

一、概念concept、notion 是同义词&#xff0c;一般可以互换&#xff0c;例如&#xff1a; The notion/concept of public keys is introduced in the paper “New Direction of Cryptography” half a century ago. Public keys have been widely accepted as a cryptographi…

韩顺平Java | C23 反射Reflection

需求&#xff1a;通过外部文件配置&#xff0c;在不修改源码情况下控制程序&#xff08;符合设计模式ocp开闭原则&#xff1a;不修改源码的情况下扩容功能&#xff09; ※反射机制 反射机制允许程序在执行期间借助于ReflectioAPI取得任何类的内部信息&#xff08;如成员变量&…

跨境金融区块链服务平台

跨境金融服务是因企业及个人跨境经营、交易、投资、往来等活动而产生的资金使用、调拨、配置等需求&#xff0c;而提供的金融服务。近年来&#xff0c;随着我国经济的快速稳步增长和全球化经济一体化的不断深入发展&#xff0c;跨境金融业务增长迅速&#xff0c;监管也开始转化…

AcWing 731. 毕业旅行问题(每日一题)

原题链接&#xff1a;731. 毕业旅行问题 - AcWing题库 此题难度较大&#xff0c;是2019年字节跳动校招题&#xff0c;里面涉及位运算与状态压缩DP&#xff0c;不会的可以去学习&#xff0c;此题根据个人量力而行。 建议看一下y总的讲解&#xff1a;AcWing 731. 毕业旅行问题&…

初识MySQL(中篇)

使用语言 MySQL 使用工具 Navicat Premium 16 代码能力快速提升小方法&#xff0c;看完代码自己敲一遍&#xff0c;十分有用 目录 1.SQL语言 1.1 SQL语言组成部分 2.MySQL数据类型 2.1 数值类型 2.2 字符串类型 2.3 日期类型 3.创建数据表 3.1 创建数据表方法1 …

【A 类比赛】大学生学科竞赛智慧应用场景题目大全

智能应用的多彩场景&#xff1a;未来生活的无限可能 随着科技的飞速发展&#xff0c;智能应用已经渗透到我们生活的方方面面&#xff0c;它们不仅极大地提高了工作效率&#xff0c;也丰富了我们的生活体验。从家庭到工作场所&#xff0c;从城市到乡村&#xff0c;智能应用正在…

vLLM 部署大模型

1 介绍 vLLM 是来自 UC Berkeley 的 LMSYS 在 LLM 推理方面的最新工作&#xff08;没错就是搞出 Vicuna 的那个 group&#xff09;&#xff0c;最大亮点是采用 Paged Attention 技术&#xff0c;结合 Continuous Batching&#xff0c;极大地优化了 realtime 场景下的 LLM serv…