通讯录(单链表思想)

文章目录

  • 通讯录 2.0
    • 头文件
    • 通讯录操作函数
    • 通讯录主函数

通讯录 2.0

之前分享过使用顺序表思想实现通讯录,现在分享使用单链表实现的通讯录,我们只需要规定每个链表的元素是结构体类型,每个结构体内存放联系人信息即可。
**不断地练习才能熟练掌握!**代码逻辑很简单,实现时注意边界的处理即可。

头文件

//Contact.h#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#define NAME_MAX 100
#define GENDER_MAX 4
#define TEL_MAX 11//用户数据
typedef struct PersonInfo
{char name[NAME_MAX];char gender[GENDER_MAX];size_t age;char tel[TEL_MAX];
}PeoInfo;typedef struct Contact
{PeoInfo data;struct Contact* next;
}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);

通讯录操作函数

通讯录

//Contact.c#include "Contact.h"void InitContact(contact** con)
{*con = NULL;
}void AddContact(contact** con)
{assert(con);PeoInfo new;printf("请输入新联系人的姓名:\n");scanf("%s", new.name);printf("请输入新联系人的年龄:\n");scanf("%zd", &new.age);printf("请输入新联系人的电话:\n");scanf("%s", new.tel);printf("请输入新联系人的性别:\n");scanf("%s", new.gender);contact* newnode = (contact*)malloc(sizeof(contact));if (NULL == newnode){perror("malloc");exit(-1);}newnode->data = new;newnode->next = NULL;if (*con == NULL){*con = newnode;return;}contact* cur = *con;while (cur->next){cur = cur->next;}cur->next = newnode;
}void DelContact(contact** con)
{//链表为空if (!(*con)){printf("通讯录为空!\n");return;}char newname[NAME_MAX] = { 0 };printf("请输入要删除的联系人的姓名:\n");scanf("%s", newname);//链表首结点元素匹配,避免后续prev为NULL时,对它解引用if (strcmp((*con)->data.name, newname) == 0){if ((*con)->next == NULL){free(*con);*con = NULL;}else{contact* tmp = (*con)->next;free(*con);*con = tmp;}printf("删除成功!\n");return;}contact* cur = (*con)->next;contact* prev = *con;while (cur){if (strcmp(newname, cur->data.name) == 0){prev->next = cur->next;free(cur);printf("删除成功!\n");return;}prev = cur;cur = cur->next;}printf("您要删除的联系人不存在!\n");
}void ShowContact(contact* con)
{if (!con){printf("通讯录为空!\n");}printf("----------------------------------------------------------------------------------\n");printf("%-11s %-11s %-11s %-11s\n", "姓名", "年龄", "电话", "性别");contact* cur = con;while (cur){printf("%-11s %-11zd %-11s %-11s\n", cur->data.name, cur->data.age, cur->data.tel, cur->data.gender);cur = cur->next;}printf("----------------------------------------------------------------------------------\n");
}void FindContact(contact* con)
{if (!con){printf("通讯录为空!\n");return;}printf("请输入您要查询的联系人的姓名:\n");char find[NAME_MAX] = { 0 };scanf("%s", find);contact* cur = con;while (cur){if (strcmp(find, cur->data.name) == 0){printf("查询结果如下:\n");printf("%-11s %-11zd %-11s %-11s\n", cur->data.name, cur->data.age, cur->data.tel, cur->data.gender);return;}cur = cur->next;}printf("您要查询的联系人不存在!\n");
}void ModifyContact(contact** con)
{if (!(*con)){printf("通讯录为空!\n");return;}printf("请输入您要修改的联系人的姓名:\n");char obj[NAME_MAX] = { 0 };scanf("%s", obj);//char newname[NAME_MAX] = { 0 };//int newage = 0;//char newtel[TEL_MAX] = { 0 };//char newgender[GENDER_MAX] = { 0 };contact* cur = *con;while (cur){if (strcmp(obj, cur->data.name) == 0){printf("请输入修改后的姓名:\n");scanf("%s", cur->data.name);printf("请输入修改后的年龄:\n");scanf("%zd", &(cur->data.age));printf("请输入修改后的电话:\n");scanf("%s", cur->data.tel);printf("请输入修改后的性别:\n");scanf("%s", cur->data.gender);printf("修改成功!\n");return;}cur = cur->next;}printf("您要修改的联系人不存在!\n");
}void DestroyContact(contact** con)
{contact* cur = *con;while (cur){contact* tail = cur->next;free(cur);cur = tail;}*con = NULL;
}

通讯录主函数

包括菜单、读取数据、保存数据的函数实现。

//test.c#include "Contact.h"
//菜单
void menu()
{printf("******************通讯录*******************\n");printf("*******1.添加联系人     2.删除联系人*******\n");printf("*******3.修改联系人     4.查询联系人*******\n");printf("*******5.展示通讯录     0.退出通讯录*******\n");printf("*******************************************\n");
}//载入数据函数
void LoadContact(contact** con)
{FILE* pf = fopen("Contact.txt", "rb");if (NULL == pf){perror("fopen");exit(-1);}PeoInfo buff;while (fread(&buff, sizeof(PeoInfo), 1, pf)){contact* newnode = (contact*)malloc(sizeof(contact));if (NULL == newnode){perror("malloc");exit(-1);}newnode->next = NULL;newnode->data = buff;if (*con == NULL){*con = newnode;continue;}contact* cur = *con;while (cur->next){cur = cur->next;}cur->next = newnode;}printf("历史数据载入成功!\n");
}//保存数据函数
void SaveContact(contact* con)
{FILE* pf = fopen("Contact.txt", "wb");if (NULL == pf){perror("fopen");exit(-1);}contact* cur = con;while (cur){PeoInfo wr = cur->data;fwrite(&wr, sizeof(PeoInfo), 1, pf);cur = cur->next;}printf("数据保存成功!\n");
}//主函数
int main()
{contact* con;InitContact(&con);LoadContact(&con);int input = 0;do{menu();printf("请输入你想执行的操作:\n");scanf("%d", &input);switch (input){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3:ModifyContact(&con);break;case 4:FindContact(con);break;case 5:ShowContact(con);break;case 0:printf("退出通讯录\n");break;default:printf("输入非法,请重新输入!\n");break;}} while (input);SaveContact(con);DestroyContact(&con);return 0;
}

执行程序的效果:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

医用分子筛制氧机设计规范详细介绍

随着技术的不断进步&#xff0c;医用分子筛制氧机作为现代领域的重要设备&#xff0c;其设计规范显得尤为重要。本文将详细阐述医用分子筛制氧机的设计规范&#xff0c;确保设备的性能稳定、安全可靠。 一、设计原则 医用分子筛制氧机的设计应遵循安全、高效、稳定、易维护的原…

MySQL的权限管理

MySQL的权限管理 在理解MySQL的权限管理之前&#xff0c;我们需要先了解其架构设计以及权限管理在该架构中的定位。 MySQL的架构设计 MySQL数据库系统采用了分层的架构设计&#xff0c;主要可以分为以下几个层级&#xff1a; 连接层&#xff1a;最外层&#xff0c;处理连接…

设计一个通知系统

设计的系统支持不同类型消息的发送&#xff0c;例如push消息&#xff0c;sms消息和邮箱消息&#xff0c;能够支持千万级别的发送&#xff0c;保证消息推送的幂等性。系统结构图如下&#xff1a; 系统架构图中各组件作用说明&#xff1a; device/setting/user info&#xff1a;…

Python大数据分析——一元与多元线性回归模型

Python大数据分析——一元与多元线性回归模型 相关分析概念示例 一元线性回归模型概念理论分析函数示例 多元线性回归模型概念理论分析示例 线性回归模型的假设检验模型的F检验理论分析示例 模型的T检验理论分析示例 相关分析 概念 a 正相关&#xff1b;b 负相关&#xff1b;c…

Python数据分析案例42——基于Attention-BiGRU的时间序列数据预测

承接上一篇的学术缝合&#xff0c;排列组合模型&#xff0c;本次继续缝合模型演示。 Python数据分析案例41——基于CNN-BiLSTM的沪深300收盘价预测-CSDN博客 案例背景 虽然我自己基于各种循环神经网络做时间序列的预测已经做烂了.....但是还是会有很多刚读研究生或者是别的领…

VK1618 SOP18/DIP18高稳定LED驱动IC防干扰数显驱动控制器计量插座数显芯片 FAE支持

产品型号&#xff1a;VK1618 产品品牌&#xff1a;永嘉微电/VINKA 封装形式&#xff1a;SOP18/ DIP18 原厂&#xff0c;工程服务&#xff0c;技术支持&#xff01; 概述 VK1618是一种带键盘扫描接口的数码管或点阵LED驱动控制专用芯片&#xff0c;内部集成有3线串行接口、数…

Java GUI制作双人对打游戏(上)

文章目录 前言什么是Java GUI一、打开IDEA 新建一个Maven项目(后续可以打包、引入相关依赖也很容易)二、引入依赖三.绘制UI界面四.绘制JPanel面板总结 前言 什么是Java GUI Java UI&#xff0c;即Java用户界面&#xff0c;是指使用Java编程语言创建的图形用户界面&#xff08…

【MATLAB源码-第41期】基于压缩感知算法的OFDM系统信道估计和LS算法对比仿真。

操作环境&#xff1a; MATLAB 2013b 1、算法描述 压缩感知&#xff08;Compressed Sensing, CS&#xff09;是一种从稀疏或可压缩信号中重构完整信号的数学理论和技术。下面详细介绍压缩感知和它在OFDM信道估计中的应用。 1. 压缩感知基本概念 在传统采样理论中&#xff0c…

【C++】C++11 lambda表达式

&#x1f440;樊梓慕&#xff1a;个人主页 &#x1f3a5;个人专栏&#xff1a;《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C》《Linux》《算法》 &#x1f31d;每一个不曾起舞的日子&#xff0c;都是对生命的辜负 目录 前言 C11引入『 lambda表…

25. 【Android教程】列表控件 ListView

在学习了 ScrollView 及 Adapter 两节内容之后&#xff0c;大家应该对 ListView 有了一些基本的了解&#xff0c;它是一个列表样式的 ViewGroup&#xff0c;将若干 item 按行排列。ListView 是一个很基本的控件也是 Android 中最重要的控件之一。它可以帮助我们完成多个 View 的…

ROS2从入门到精通1-3:详解ROS2动作通信机制与自定义动作

目录 0 专栏介绍1 动作通信模型2 动作模型实现(C)3 动作模型实现(Python)4 自定义动作 0 专栏介绍 本专栏旨在通过对ROS2的系统学习&#xff0c;掌握ROS2底层基本分布式原理&#xff0c;并具有机器人建模和应用ROS2进行实际项目的开发和调试的工程能力。 &#x1f680;详情&a…

【Linux深造日志】运维工程师必会Linux常见命令以及周边知识!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引入 哈喽各位宝子们好啊&#xff01;我是博主鸽芷咕。日志这个东西我相信大家都不陌生&#xff0c;在 linxu/Windows 系统…