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

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 查看通讯录

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

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

相关文章

蓝桥杯 每日2题 day5

碎碎念&#xff1a;哦哈呦&#xff0c;到第二天也是哦哈哟&#xff0c;&#xff0c;学前缀和差分学了半天&#xff01;day6堂堂连载&#xff01; 0.单词分析 14.单词分析 - 蓝桥云课 (lanqiao.cn) 关于这题就差在input前加一个sorted&#xff0c;记录一下下。接下来就是用字…

【饿了么笔试题汇总】[全网首发]2024-04-12-饿了么春招笔试题-三语言题解(CPP/Python/Java)

&#x1f36d; 大家好这里是KK爱Coding &#xff0c;一枚热爱算法的程序员 ✨ 本系列打算持续跟新饿了么近期的春秋招笔试题汇总&#xff5e; &#x1f4bb; ACM银牌&#x1f948;| 多次AK大厂笔试 &#xff5c; 编程一对一辅导 &#x1f44f; 感谢大家的订阅➕ 和 喜欢&#x…

决策树与随机森林实验报告(纯Python实现)

一、实验内容简介 该实验主要利用ID3算法和已有的数据建立决策树和随机森林&#xff0c;并利用决策树和随机森林来预测未知数据的值。本实验使用Python实现。 二、算法说明 下面介绍几个基础但很重要的概念&#xff1a; 决策树&#xff1a;决策树是在已知各种情况发生概率的…

如何恢复 iPhone 删除的照片?

照片是iPhone空间不足的主要原因&#xff0c;因此许多用户选择删除一些重复或不喜欢的图片来释放设备。然而&#xff0c;人们在清洁过程中不小心遗漏了自己喜欢的照片的情况很常见。如果你找不到这些珍贵的照片&#xff0c;你一定很难过。其实&#xff0c;您不必担心这个问题&a…

Android 纵向双选日历

这个日历的布局分两部分&#xff0c;一部分是显示星期几的LinearLayout&#xff0c;另外就是一个RecyclerView&#xff0c;负责纵向滚动了。 工具类&#xff1a; implementation com.blankj:utilcode:1.17.3上activity_calendar代码&#xff1a; <?xml version"1.0&…

【教资】总结经验篇

4月.12日概述 今天是2024年上半学期中小学出成绩的一天&#xff0c;查到成绩的那一刻是灰常让人激动的&#xff0c;很开心&#xff0c;特此记下此时的真实感受&#xff0c;我也没有去问别人怎么样&#xff0c;特此针对自己以记之&#xff0c;加上最近有点摆烂&#xff0c;所以…

重磅!李彦宏内部讲话曝光,百度AI闭源策略引爆争议!|TodayAI

最近&#xff0c;百度公司创始人、董事长兼CEO李彦宏的一次内部讲话内容被公之于众。在这次讲话中&#xff0c;李彦宏表达了几个与行业普遍看法相左的观点&#xff0c;尤其在开源与闭源策略的选择上&#xff0c;引发了业界的广泛关注和讨论。 李彦宏在讲话中明确指出了百度对开…

gitlab、jenkins安装及使用文档二

安装 jenkins IP地址操作系统服务版本192.168.75.137Rocky9.2jenkins 2.450-1.1 jdk 11.0.22 git 2.39.3192.168.75.138Rocky9.2gitlab-ce 16.10.0 结合上文 jenkins安装 前期准备&#xff1a; yum install -y epel-release yum -y install net-tools vim lrzsz wget…

git知识

如何将develop分支合并到master分支 #简单版 git checkout master git pull origin master git merge origin/develop # 解决可能的冲突并提交 git push origin master#复杂版 git checkout master # 拉取远程 master 分支的最新代码并合并到本地 git pull origin master # 拉…

网页内容生成图片,这18般武艺你会几种呢?

前言 关于【SSD系列】&#xff1a; 前端一些有意思的内容&#xff0c;旨在3-10分钟里&#xff0c; 500-1000字&#xff0c;有所获&#xff0c;又不为所累。 网页截图&#xff0c;windows内置了快捷命令和软件&#xff0c;chrome开发者工具也能一键截图&#xff0c;html2canva…

【Linux杂货铺】文件系统

目录 &#x1f308;前言&#x1f308; &#x1f4c1; 硬盘 &#x1f4c2; 物理结构 &#x1f4c2; 存储结构 &#x1f4c2; CHS定址法 &#x1f4c2; 操作系统对硬盘的管理和抽象 &#x1f4c1; 文件系统 &#x1f4c2; 分区 &#x1f4c2; 分组 &#x1f4c2; inode号 分配…

DL00295-基于AirSim仿真环境的无人机深度强化学习算法路径规划完整实现含详细说明文档

-创建了一个开放的AI Gym环境&#xff0c;包括多旋翼和固定翼无人机的运动学模型。 -提供了一些UE4环境来训练和测试深度强化学习DRL导航策略。 -基于AirSim和SB3。 完整代码链接见文末。 DL00295-基于AirSim仿真环境的无人机深度强化学习算法路径规划完整实现含详细说明文档

力扣HOT100 - 189. 轮转数组

解题思路&#xff1a; 三次反转。 先反转一次&#xff0c;再根据 k 拆分成两部分各反转一次。 class Solution {public void rotate(int[] nums, int k) {k % nums.length;reverse(nums, 0, nums.length - 1);reverse(nums, 0, k - 1);reverse(nums, k, nums.length - 1);}pu…

【QT教程】QT6 Web性能优化

QT6 Web性能优化 使用AI技术辅助生成 QT界面美化视频课程 QT性能优化视频课程 QT原理与源码分析视频课程 QT QML C扩展开发视频课程 免费QT视频课程 您可以看免费1000个QT技术视频 免费QT视频课程 QT统计图和QT数据可视化视频免费看 免费QT视频课程 QT性能优化视频免费看 免费…

MURF1040CT-ASEMI快恢复二极管MURF1040CT

编辑&#xff1a;ll MURF1040CT-ASEMI快恢复二极管MURF1040CT 型号&#xff1a;MURF1040CT 品牌&#xff1a;ASEMI 封装&#xff1a;TO-220F 最大平均正向电流&#xff08;IF&#xff09;&#xff1a;10A 最大循环峰值反向电压&#xff08;VRRM&#xff09;&#xff1a;4…

kubectl_入门_Pod配置以及生命周期

Pod配置以及生命周期 1. Pod结构定义 每个pod中都可以包含一个或多个容器&#xff0c;这些容器可以分为两类 用户程序所在的容器&#xff0c;数量可多可少Pause容器&#xff0c;这是每个Pod都会有的一个根容器&#xff0c;它的作用有两个 可以以它为根据&#xff0c;评估整个…

工业相机飞拍功能的介绍(转载学习)

转载至&#xff1a; https://baijiahao.baidu.com/s?id1781438589726948322&wfrspider&forpc

【Python使用】嘿马头条完整开发md笔记第5篇:数据库,1 Redis事务【附代码文档】

嘿马头条项目从到完整开发笔记总结完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;课程简介&#xff0c;ToutiaoWeb虚拟机使用说明1 产品介绍,2 原型图与UI图,3 技术架构,4 开发,1 需求,2 注意事项。数据库&#xff0c;理解ORM1 简介,2 安装,3 数据库连接…

基于SSM学生考勤管理系统需求(内附设计LW + PPT+ 源码下载)

摘 要 高校的不断扩张让在校学生数量不断的增加&#xff0c;对于教师和管理人员的需求也在不断地增强&#xff0c;对日常的学生考勤管理的工作量也在日益增加&#xff0c;传统的人工点名签到的考勤管理模式已经给无法适用于当前高校考勤管理的需求&#xff0c;同时手动录入的…

一、flask入门和视图

run启动参数 模板渲染 后端给前端页面传参 前端页面设置css from flask import Flask, render_template,jsonify# 创建flask对象 app = Flask(__name__)# 视图函数 + 路由route @app.route("/") def hello_world():# 响应,返回给前端的数据return "hello worl…