单链表和文件操作使用练习:通讯录

news2024/12/23 5:27:04

1. 项目文件组成(vs2022)

1. Contact.h和Contact.c分别为实现通讯录的头文件和源文件。

2. SList.h和SList.c分别为实现单链表的头文件和源文件。

3. test.c为测试用的源文件,用于调用通讯录提供的函数。

4. Contact.txt用于存储联系人信息。


 

2. 单链表

C语言单链表-CSDN博客 

2.1 头文件

对于该项目,有用的接口就四个。

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include "Contact.h"

typedef PeoInfo SLTDataType;

typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头删
void SLTPopFront(SLTNode** pphead);
//删除pos位置节点
void SLTErase(SLTNode** pphead, SLTNode* pos);
//申请结点
SLTNode* SLTBuyNode(SLTDataType x);

2.2 源文件

#define _CRT_SECURE_NO_WARNINGS
#include "SList.h"

//创建新结点
SLTNode* SLTBuyNode(SLTDataType x)
{
	SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->data = x;
	newnode->next = NULL;
	return newnode;
}

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{
	assert(pphead);
	SLTNode* newnode = SLTBuyNode(x);

	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		SLTNode* ptail = *pphead;
		while (ptail->next != NULL)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}
}

//头删
void SLTPopFront(SLTNode** pphead)
{
	assert(pphead && *pphead);
	SLTNode* newphead = (*pphead)->next;
	free(*pphead);
	*pphead = newphead;
}

//删除pos位置节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{
	assert(pphead && *pphead);
	assert(pos);

	if (pos == *pphead)
	{
		SLTPopFront(pphead);
	}
	else
	{
		SLTNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = pos->next;
		free(pos);
	}
}

 


3. 通讯录

3.1 头文件

#pragma once
#define NAME_MAX 100
#define SEX_MAX 10
#define TEL_MAX 11
#define ADDR_MAX 100

//前置声明
typedef struct SListNode contact;

//用户数据
typedef struct PersonInfo
{
    char name[NAME_MAX];
    char sex[SEX_MAX];
    int age;
    char tel[TEL_MAX];
    char addr[ADDR_MAX];
}PeoInfo;

//初始化通讯录
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);

3.2 源文件

#define _CRT_SECURE_NO_WARNINGS
#include "Contact.h"
#include "SList.h"

//初始化通讯录
void InitContact(contact** con)
{
	*con = NULL;
	FILE* pf = fopen("Contact.txt", "rb");
	if (pf == NULL)
	{
		perror("fopen");
		exit(-1);
	}
	PeoInfo tmp;
	contact* pcur = *con;
	while (fread(&tmp, sizeof(PeoInfo), 1, pf) == 1)
	{
		if (*con == NULL)
		{
			*con = SLTBuyNode(tmp);
			pcur = *con;
		}
		else
		{
			pcur->next = SLTBuyNode(tmp);
			pcur = pcur->next;
		}
	}
	fclose(pf);
}

//添加通讯录数据
void AddContact(contact** con)
{
	static PeoInfo newpeo;
	printf("请输入新联系人姓名:>");
	scanf("%s", newpeo.name);
	printf("请输入新联系人性别:>");
	scanf("%s", newpeo.sex);
	printf("请输入新联系人年龄:>");
	scanf("%d", &(newpeo.age));
	printf("请输入新联系人电话:>");
	scanf("%s", newpeo.tel);
	printf("请输入新联系人地址:>");
	scanf("%s", newpeo.addr);

	SLTPushBack(con, newpeo);
	printf("添加成功!\n");

	//system("pause"); fflush(stdin); system("cls");
}

//销毁通讯录数据
void DestroyContact(contact** con)
{
	FILE* pf = fopen("Contact.txt", "wb");
	if (pf == NULL)
	{
		perror("fopen");
		exit(-1);
	}
	contact* pcur = *con;
	*con = NULL;
	while (pcur != NULL)
	{
		contact* del = pcur;
		pcur = pcur->next;
		fwrite(del, sizeof(PeoInfo), 1, pf);
		free(del);
		del = NULL;
	}
	fclose(pf);
}

//按名字查找
contact* ConFindByName(contact* con, char* name)
{
	assert(con);
	contact* pcur = con;
	while (pcur != NULL)
	{
		if (strcmp(pcur->data.name, name) == 0)
			return pcur;
		pcur = pcur->next;
	}
	return NULL;
}

//删除通讯录数据
void DelContact(contact** con)
{
	assert(*con);
	char name[NAME_MAX];
	printf("请输入要删除的联系人的姓名:>");
	scanf("%s", name);
	contact* find = ConFindByName(*con, name);
	if (find == NULL)
	{
		printf("查无此人!\n");
	}
	else
	{
		SLTErase(con, find);
		printf("删除成功!\n");
	}
}

//展示通讯录数据
void ShowContact(contact* con)
{
	if (con == NULL)
	{
		printf("暂无联系人!\n");
		return;
	}
	contact* pcur = con;
	printf("%-10s\t%-10s\t%-5s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
	while (pcur != NULL)
	{
		printf("%-10s\t%-10s\t%-5d\t%-20s\t%-20s\n", pcur->data.name, pcur->data.sex, pcur->data.age, pcur->data.tel, pcur->data.addr);
		pcur = pcur->next;
	}
}

//查找通讯录数据
void FindContact(contact* con)
{
	assert(con);
	char name[NAME_MAX];
	printf("请输入要查找的联系人的姓名:>");
	scanf("%s", name);
	contact* find = ConFindByName(con, name);
	if (find == NULL)
	{
		printf("查无此人!\n");
	}
	else
	{
		printf("%-10s\t%-10s\t%-5s\t%-20s\t%-20s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-10s\t%-10s\t%-5d\t%-20s\t%-20s\n", find->data.name, find->data.sex, find->data.age, find->data.tel, find->data.addr);
	}
}

//修改通讯录数据
void ModifyContact(contact** con)
{
	assert(*con);
	char name[NAME_MAX];
	printf("请输入要修改的联系人的姓名:>");
	scanf("%s", name);
	contact* find = ConFindByName(*con, name);
	if (find == NULL)
	{
		printf("查无此人!\n");
	}
	else
	{
		printf("请输入该联系人的新名字:>");
		scanf("%s", find->data.name);
		printf("请输入该联系人的新性别:>");
		scanf("%s", find->data.sex);
		printf("请输入该联系人的新年龄:>");
		scanf("%d", &(find->data.age));
		printf("请输入该联系人的新电话:>");
		scanf("%s", find->data.tel);
		printf("请输入该联系人的新地址:>");
		scanf("%s", find->data.addr);

		printf("修改成功!\n");
	}
}

4. test.c

#define _CRT_SECURE_NO_WARNINGS
#include "Contact.h"
#include "SList.h"

enum options
{
	Exit,
	Add,
	Del,
	Find,
	Modi,
	Show
};

void menu()
{
	printf("||=========通讯录=========||\n");
	printf("||======1.增加联系人======||\n");
	printf("||======2.删除联系人======||\n");
	printf("||======3.查找联系人======||\n");
	printf("||======4.修改联系人======||\n");
	printf("||======5.查看通讯录======||\n");
	printf("||=========0.退出=========||\n");
}

int main()
{
	contact* con;
	InitContact(&con);
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case Exit:
            DestroyContact(&con);
			printf("退出!\n");
			break;
		case Add:
			AddContact(&con);
			break;
		case Del:
			DelContact(&con);
			break;
		case Find:
			FindContact(con);
			break;
		case Modi:
			ModifyContact(&con);
			break;
		case Show:
			ShowContact(con);
			break;
		default:
			printf("输入错误,请重新输入!\n");
			break;
		}
		system("pause"); fflush(stdin); system("cls");
	} while (input);


	return 0;
}

下面这一行的作用是

1. 暂停让用户看执行结果。

2. 清除输入缓存,防止输入粘连。

3. 清空屏幕,以免屏幕上留下太多信息。

system("pause"); fflush(stdin); system("cls");

5. 运行展示

5.1 增加联系人

5.2 删除联系人

 5.3 查找联系人

5.4 修改联系人

 5.5 查看通讯录

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

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

相关文章

外卖点餐APP开发需要哪些功能

uni-app框架&#xff1a;使用Vue.js开发跨平台应用的前端框架&#xff0c;编写一套代码&#xff0c;可编译到Android、小程序等平台。 框架支持:springboot/Ssm/thinkphp/django/flask/express均支持 前端开发:vue.js 可选语言&#xff1a;pythonjavanode.jsphp均支持 运行软件…

对比试验和作图技巧

不同框架模型的对比试验http://t.csdnimg.cn/ewRsI深度强化学习算法研究中的常用对比试验及作图技巧http://t.csdnimg.cn/3Hef1

好几万人都在关注的开源物联网平台

项目介绍 ThingsBoard是一个功能强大且灵活的物联网平台&#xff0c;它提供了设备连接、数据处理、可视化展示以及规则引擎等一系列核心功能。该平台采用微服务架构&#xff0c;具有良好的扩展性和可定制性&#xff0c;能够满足不同规模、不同需求的物联网应用。 功能特点 1.设…

UE5数字孪生系列笔记(四)

场景的切换 创建一个按钮的用户界面UMG 创建一个Actor&#xff0c;然后将此按钮UMG添加到组件Actor中 调节几个全屏的背景 运行结果 目标点切换功能制作 设置角色到这个按钮的位置效果 按钮被点击就进行跳转 多个地点的切换与旋转 将之前的目标点切换逻辑替换成旋转的逻…

技术速递|为 .NET iOS 和 .NET MAUI 应用程序添加 Apple 隐私清单支持

作者&#xff1a;Gerald Versluis 排版&#xff1a;Alan Wang Apple 正在推出一项隐私政策&#xff0c;将隐私清单文件包含在针对 App Store 上的 iOS、iPadOS 和 tvOS 平台的新应用程序和更新应用程序中。请注意&#xff0c;至少目前 macOS 应用程序被排除在外。 隐私清单文件…

javaWeb项目-外面点餐系统功能介绍

项目关键技术 开发工具&#xff1a;IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7 框架&#xff1a;ssm、Springboot 前端&#xff1a;Vue、ElementUI 关键技术&#xff1a;springboot、SSM、vue、MYSQL、MAVEN 数据库工具&#xff1a;Navicat、SQLyog 1、Spring Boot框架 …

云服务器降价,阿里腾讯华为京东云优惠价格表整理

现在租一个服务器多少一个月&#xff1f;优惠价格低至3.8元1个月&#xff0c;租用一个月云服务器收费价格表&#xff1a;阿里云和腾讯云2核2G3M服务器优惠价格61元一年&#xff0c;折合一个月5元&#xff0c;京东云轻量云主机5.8元一个月&#xff0c;华为云服务器优惠价格3.8元…

状态模式【行为模式C++】

1.概述 状态模式是一种行为设计模式&#xff0c; 让你能在一个对象的内部状态变化时改变其行为&#xff0c; 使其看上去就像改变了自身所属的类一样。 2.结构 State(抽象状态类)&#xff1a;定义一个接口用来封装与上下文类的一个特定状态相关的行为&#xff0c;可以有一个或多…

家居网购项目(权限验证+事务管理)

文章目录 1.过滤器权限认证1.程序框架图2.web.xml3.编写AdminAuthorization4.编写MemberAuthorization5.细节6.结果展示1.未登录可以任意浏览商品2.点击添加购物车提示登录3.点击后台管理&#xff0c;提示管理员登录4.也做了其余资源的访问验证 2.事务管理1.思路分析2.重写JDBC…

AI大模型日报#0415:贾佳亚团队新作王炸、马斯克首款多模态大模型、ChatGPT to B

导读&#xff1a; 欢迎阅读《AI大模型日报》&#xff0c;内容基于Python爬虫和LLM自动生成。目前采用“文心一言”生成了每条资讯的摘要。标题: 融合ChatGPTDALLE3&#xff0c;贾佳亚团队新作开源&#xff1a;识图推理生图一站解决 摘要: 贾佳亚团队推出了多模态模型Mini-Gem…

Android11应用安装未知来源的权限改动

最近开发的App需要下载安装另一个App。这就涉及到了app的安装代码。关于App的安装代码&#xff0c;写了不少&#xff0c;所以这一块觉得不是问题&#xff1a; 判断版本&#xff0c;Android8.0判断是否有未知来源安装全选&#xff0c;没有则打开未知来源安装权限设置界面去开启…

pdf预览空白问题解决。第一次预览正常,再重新打开就空白的问题。是因为cmaps没有更新

文章目录 问题描述问题解决问题总结曾经参考过的文章&#xff08;也未能解决&#xff09; 问题描述 我用的是pdfjs作为PDF预览工具使用。 预览有电子签章的PDF后(如下图的水印、签章)&#xff0c;再重新预览没有电子签章的PDF&#xff0c;就会空白。 如上图&#xff0c;第一个…

【Linux】磁盘管理和文件系统

目录 一、硬盘 1.硬盘结构 2.结构类型 二、MBR与磁盘分区 1.MBR主引导记录 2.磁盘分区结构 三、文件系统类型 四、linux系统添加并使用新硬盘的步骤 1.添加新的硬盘 2.刷新识别 3.进行分区 4.格式化&#xff0c;创建文件系统 5.挂载使用 一、硬盘 1.硬盘结构…

什么是人力资源成本?人力资源成本有哪些?

人力资源成本是企业运营成本的重要组成部分&#xff0c;对企业的财务状况和经营效率有着直接影响&#xff0c;如今企业面临着持续的成本压力和效率挑战。人力资源成本不仅直接关联企业的运营效率&#xff0c;还影响着企业的长期战略发展。因此&#xff0c;如何优化人力资源成本…

二、变量和引用

目录 2.1 什么是变量 2.2变量的命名 2.3 变量的类型 2.3.1 根据数据类型分类 2.3.2 根据作用域分类 2.4 变量的定义 2.5 shell中的引用 在程序设计语言中&#xff0c;变量是一个非常重要的概念。也是初学者在进行Shell程序设计之前必须掌握的一个非常基础的概念。只有理…

D3-八数码

D3-八数码 题目描述解题思路代码如下 题目描述 解题思路 本题若直接在3*3网格中思考较为困难&#xff0c;可以转换为一维的字符串&#xff0c;在一维字符串中考虑较为简单&#xff0c;要注意本题中两个字符交换位置时只能是x和另外字符交换&#xff0c;本题另外一个难点在于如何…

借力社交裂变,Xinstall助你实现用户快速增长

在数字化时代&#xff0c;社交裂变已成为品牌获取新用户、扩大影响力的关键手段。然而&#xff0c;如何有效利用社交裂变&#xff0c;实现用户快速增长&#xff0c;却是许多品牌面临的挑战。今天&#xff0c;我们将为大家介绍一个强大的社交裂变引擎——Xinstall&#xff0c;它…

Cesium 无人机航线规划

鉴于大疆司空平台和大疆无人机app高度绑定&#xff0c;导致很多东西没办法定制化。 从去年的时候就打算仿大疆开发一套完整的平台&#xff0c;包括无人机app以及仿司空2的管理平台&#xff0c;集航线规划、任务派发、实时图像、无人机管理等功能的平台。 当前阶段主要实现了&…

包装类初识泛型

一.包装类 在Java中, 基本类型不继承于Object类. 所以为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型.(包装类型相当于引用类型) 1.基本类型对应的包装类 byte -- Byteshort -- Shortint -- Integerlong -- Longfloat -- Floatdouble -- Doublech…

20V/3A大电流线性稳压器替代MIC29302/MIC29300

概述(替代MIC29302/MIC29300) PCD3942 是一款低压差稳压器&#xff0c;专为快速瞬态响应而优化。该装置能够提供 3A 的输出电流&#xff0c;典型压降为 325mV。工作静态电流为 1mA&#xff0c;关机时降至 1μA 以下&#xff0c;同时压差模式下静态电流控制良好。除了快速瞬态响…