C语言:基于单链表实现通讯录项目

news2024/11/15 5:45:01

前言

之前我们用顺序表实现了通讯录,这次我们使用单链表实现。我们定义五个文件,

SingleLinkedList.h   SingleLinkedList.c  Contact.h Contact.c test.c

SingleLinkedList.h 是包含了单链表的结构,及各类库文件声明,各个单链表接口声明

SingleLinkedList.c 用于实现各类单链表接口

Contact.h是包含了通讯录的结构,各个通讯录接口声明

Contact.c用于实现通讯录接口

test.c用作测试和实现通讯录的菜单,控制增删查改的选项

SingleLinkedList.h文件

在我的上一篇博客中已经实现过单链表了,所以这里不作实现讲解

SingleLinkedList.h文件:
#define _CRT_SECURE_NO_WARNINGS	1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include"Contact.h"
#include"string.h"
#include<windows.h>
typedef PeoInfo SLLDataType;
typedef struct _SingleLinkedListNode
{
	SLLDataType x;
	struct _SingleLinkedListNode* next;
}SLLNode;
//获取一个新节点
SLLNode* BuynewNode(SLLDataType x);
//尾插
void SLLPushBack(SLLNode** pphead, SLLDataType x);
//头插
void SLLPushFront(SLLNode** pphead, SLLDataType x);
//尾删
void SLLPopBack(SLLNode** pphead);
//头删
void SLLPopFront(SLLNode** pphead);
//查找
SLLNode* SLLFind(SLLNode* phead, SLLDataType x);
//在指定位置之前插入数据
void SLLInsert(SLLNode** pphead, SLLNode* pos, SLLDataType x);
//在指定位置之后插入数据
void SLLInsertAfter(SLLNode* pos, SLLDataType x);
//删除指定位置之后的数据
void SLLEraseAfter(SLLNode* pos);
//删除指定位置的数据
void SLLErase(SLLNode** pphead, SLLNode* pos);
//打印链表
void SLLPrint(SLLNode* phead);
//销毁链表
void SLLDestroy(SLLNode** pphead);

SingleLinkedList.c文件

​
SingleLinkedList.c文件:
#include"SingleLinkedList.h"
//打印链表
//void SLLPrint(SLLNode* phead)
//{
//	SLLNode* pcur = phead;
//	while (pcur)
//	{
//		printf("%d->", pcur->x);
//		pcur = pcur->next;
//	}
//	printf("NULL\n");
//}
//获取一个新节点
SLLNode* BuynewNode(SLLDataType x)
{
	SLLNode* newnode = (SLLNode*)malloc(sizeof(SLLNode));
	if (newnode == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	newnode->x = x;
	newnode->next = NULL;
	return newnode;
}
//尾插
void SLLPushBack(SLLNode** pphead, SLLDataType x)
{
	assert(pphead);
	SLLNode* newnode = BuynewNode(x);
	if (*pphead == NULL)
	{

		*pphead = newnode;
	}
	else
	{
		SLLNode* ptail = *pphead;
		while (ptail->next)
		{
			ptail = ptail->next;
		}
		ptail->next = newnode;
	}

}
//头插
void SLLPushFront(SLLNode** pphead, SLLDataType x)
{
	assert(pphead);
	SLLNode* newnode = BuynewNode(x);
	newnode->next = *pphead;
	*pphead = newnode;
}
//尾删
void SLLPopBack(SLLNode** pphead)
{
	assert(pphead && *pphead);
	if ((*pphead)->next == NULL)
	{
		free(*pphead);
		*pphead = NULL;
	}
	else
	{
		SLLNode* prev = *pphead;
		SLLNode* ptail = *pphead;
		while (ptail->next)
		{
			prev = ptail;
			ptail = ptail->next;
		}
		prev->next = NULL;
		free(ptail);
		ptail = NULL;
	}

}
//头删
void SLLPopFront(SLLNode** pphead)
{
	assert(pphead && *pphead);
	SLLNode* next = (*pphead)->next;
	free(*pphead);
	*pphead = next;
}
//查找
//SLLNode* SLLFind(SLLNode* phead, SLLDataType x)
//{
//	assert(phead);
//	SLLNode* pcur = phead;
//	while (pcur)
//	{
//		if (pcur->x == x)
//		{
//			return pcur;
//		}
//		pcur = pcur->next;
//	}
//	return NULL;
//}
//在指定位置之前插入数据
void SLLInsert(SLLNode** pphead, SLLNode* pos, SLLDataType x)
{
	assert(pphead && *pphead);
	assert(pos);
	SLLNode* newnode = BuynewNode(x);
	if (*pphead == pos)
	{
		SLLPushFront(pphead, x);
	}
	else
	{
		SLLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		newnode->next = pos;
		prev->next = newnode;
	}

}
//在指定位置之后插入数据
void SLLInsertAfter(SLLNode* pos, SLLDataType x)
{
	assert(pos);
	SLLNode* newnode = BuynewNode(x);
	SLLNode* next = pos->next;

	newnode->next = next;
	pos->next = newnode;
}
//删除指定位置之后的数据
void SLLEraseAfter(SLLNode* pos)
{
	assert(pos && pos->next);
	SLLNode* del = pos->next;
	pos->next = del->next;
	free(del);
	del = NULL;
}
//删除指定位置的数据
void SLLErase(SLLNode** pphead, SLLNode* pos)
{
	assert(pphead && *pphead);
	assert(pos);
	if (*pphead == pos)
	{
		SLLPopFront(pphead);
	}
	else
	{
		SLLNode* del = pos;
		SLLNode* prev = *pphead;
		while (prev->next != pos)
		{
			prev = prev->next;
		}
		prev->next = del->next;
		free(pos);
		pos = NULL;
	}

}
//销毁链表
void SLLDestroy(SLLNode** pphead)
{
	assert(pphead && *pphead);
	while (*pphead)
	{
		SLLNode* next = (*pphead)->next;
		free(*pphead);
		*pphead = next;
	}

}

​

这里我们把影响Contact.c文件的部分接口注释掉。

Contact.h文件

#pragma once
#define NAME_MAX 100
#define GENDER_MAX 10
#define TEL_MAX 19
#define ADDR_MAX 100
enum
{
    EXIT ,
    ADD,
    ERASE,
    FIND,
    MODIFY,
    SHOW
};
//前置声明
typedef struct _SingleLinkedListNode Contact;
//用户数据
typedef struct PersonInfo
{
    char name[NAME_MAX];
    char gender[GENDER_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);

Contact.c文件各类接口实现

初始化通讯录

头文件声明:
void InitContact(Contact** con);
实现:
//初始化通讯录
void InitContact(Contact** con)
{
	assert(con);
	(*con) = NULL;
	PeoInfo pi;
	strcpy(pi.name,"NULL");
	strcpy(pi.gender, "NULL");
	pi.age = 0;
	strcpy(pi.tel, "NULL");
	strcpy(pi.addr, "NULL");
   SLLPushBack(con, pi);
	
}

字符数组用strcpy拷贝值,整型数据直接赋值

初始化:将数据都置为空,这样做的目的是为了再后期在通讯录没有数据的时候其他功能不会被断言报错,看一下后期实现的结果:


添加通讯录数据

头文件声明:
void AddContact(Contact** con);
实现:
//添加通讯录数据
void AddContact(Contact** con)
{
	assert(con);
	PeoInfo pi;
	printf("请输入要添加的联系人姓名:>\n");
	scanf("%s",pi.name);
	printf("请输入要添加的联系人性别:>\n");
	scanf("%s", pi.gender);
	printf("请输入要添加的联系人年龄:>\n");
	scanf("%d", &pi.age);
	printf("请输入要添加的联系人电话:>\n");
	scanf("%s", pi.tel);
	printf("请输入要添加的联系人家庭住址:>\n");
	scanf("%s", pi.addr);
     free(*con);
	*con = NULL;
	SLLPushBack(con,pi);

	printf("添加联系人信息成功!\n");
}

我们先定义一个联系人类的自定义结构体pi,将pi的各个数据填充好后,调用之前写好的尾插方法,尾插到通讯录(链表)中在尾插前,可以看到我先写了个*con=NULL,因为我之前初始化的时候,将字符串"NULL",先插入了通讯录中,只是为了后期不影响其他功能,而不能让真正意义上的通讯录打印出来的第一条数据是“NULL”,所以这里将链表先释放再置为NULL,然后再填充数据

后期的结果我们来看看:

没有数据前的通讯录:

添加数据后的通讯录:


删除通讯录数据

头文件声明:
void DelContact(Contact** con);
实现:
//删除通讯录数据
void DelContact(Contact** con)
{
	assert(con && *con);
	char name[NAME_MAX] = { 0 };
	Contact* pcur = *con;
	printf("请输入要删除的联系人姓名:>\n");
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			SLLErase(con, pcur);
			break;
		}
		else
		{
			pcur = pcur->next;
		}	
	}
	if (flag == 1)
	{
		printf("删除联系人成功!\n");
	}
	else
	{
		printf("要删除的联系人不存在\n");
	}
	
}

首先,我们定义一个字符数组,一个临时指针pcur指向*con,定义一个标志flag,当flag为1时,代表有这个数据,flag=0时代表,通讯录没有这个数据。然后输入一个姓名与我们通讯录中存在的姓名比较,如果二者相等就将flag置为1否则就不改动

SLLErase(con, pcur);

这个接口是我们之前写好的,用来删除pos位置的节点,如果找到了,那么就将这个pos位置的节点删除,那么从而实现通讯录的数据删除

来看看后期实现的效果:

删除前:

删除后:


展示通讯录数据

头文件声明:
void ShowContact(Contact* con);
实现:
//展示通讯录数据
void ShowContact(Contact* con)
{
	Contact* tmp = con;
	printf("        联系人信息\n");
	int i = 1;
	printf("序号 ""姓名 " "性别 " "年龄 " "电话 " "家庭住址\n");
	while (tmp)
	{
		
		printf(" %d %s  %s  %d  %s  %s ",i++, tmp->x.name,
			tmp->x.gender,
			tmp->x.age, tmp->x.tel,
			tmp->x.addr);
		tmp = tmp->next;
		printf("\n");
	}
	
}

实现效果:



查找通讯录数据

头文件声明:
void FindContact(Contact* con);
实现:
//查找通讯录数据
void FindContact(Contact* con)
{
	assert(con);
	char name[NAME_MAX] = { 0 };
	Contact* pcur = con;
	printf("请输入要查找的联系人姓名:>\n");
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			break;
		}
		else
		{
			pcur = pcur->next;
		}
	}
	if (flag == 1)
	{
		printf("%s的信息如下:>\n", pcur->x.name);
		printf( "姓名 " "性别 " "年龄 " "电话 " "家庭住址\n");
		printf(" %s  %s  %d  %s  %s ", pcur->x.name,
			pcur->x.gender,
			pcur->x.age, pcur->x.tel,
			pcur->x.addr);
		printf("\n");
	}
	else
	{
		printf("%s不在通讯录中\n",name);
	}
}

类似于删除操作,我们要遍历通讯录,然后找到那个对应的pcur指针,然后将pcur指针指向的结构体数据打印出来

实现效果:


 

修改通讯录数据

头文件声明:
void ModifyContact(Contact** con);
实现:
//修改通讯录数据
void ModifyContact(Contact** con)
{
	assert(con&&*con);
	printf("请输入要修改的联系人姓名:\n");
	char name[NAME_MAX] = { 0 };

	Contact* pcur = *con;
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			break;
		}
		else
		{
			pcur = pcur->next;
		}
	}
	if (flag == 1)
	{
		printf("请输入要修改的联系人姓名:>\n");
		scanf("%s", pcur->x.name);
		printf("请输入要修改的联系人性别:>\n");
		scanf("%s", pcur->x.gender);
		printf("请输入要修改的联系人年龄:>\n");
		scanf("%d", &pcur->x.age);
		printf("请输入要修改的联系人电话:>\n");
		scanf("%s", pcur->x.tel);
		printf("请输入要修改的联系人家庭住址:>\n");
		scanf("%s", pcur->x.addr);
		printf("修改成功!\n");
		printf("\n");
	}
	else
	{
		printf("%s不在通讯录中\n", name);
	}
}

实现效果:



销毁通讯录数据

头文件声明:
void DestroyContact(Contact** con);
实现:
//销毁通讯录数据
void DestroyContact(Contact** con)
{
	SLLDestroy(con);
}

通讯录的销毁就是链表的销毁,所以我们直接调用我们之前写好的销毁链表接口。

补充说明

char name[NAME_MAX] = { 0 };

	Contact* pcur = *con;
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			break;
		}
		else
		{
			pcur = pcur->next;
		}
	}

这块代码出现了很多次,其实可以封装成一个函数,多个函数进行调用,代码就不会那么冗余

完整Contact.c文件源码

#include"SingleLinkedList.h"
//初始化通讯录
void InitContact(Contact** con)
{
	assert(con);
	(*con) = NULL;
	PeoInfo pi;
	strcpy(pi.name,"NULL");
	strcpy(pi.gender, "NULL");
	pi.age = 0;
	strcpy(pi.tel, "NULL");
	strcpy(pi.addr, "NULL");
   SLLPushBack(con, pi);
	
}
//添加通讯录数据
void AddContact(Contact** con)
{
	assert(con);
	PeoInfo pi;
	printf("请输入要添加的联系人姓名:>\n");
	scanf("%s",pi.name);
	printf("请输入要添加的联系人性别:>\n");
	scanf("%s", pi.gender);
	printf("请输入要添加的联系人年龄:>\n");
	scanf("%d", &pi.age);
	printf("请输入要添加的联系人电话:>\n");
	scanf("%s", pi.tel);
	printf("请输入要添加的联系人家庭住址:>\n");
	scanf("%s", pi.addr);
	free(*con);
	*con = NULL;
	SLLPushBack(con,pi);

	printf("添加联系人信息成功!\n");
}
//展示通讯录数据
void ShowContact(Contact* con)
{
	Contact* tmp = con;
	printf("        联系人信息\n");
	int i = 1;
	printf("序号 ""姓名 " "性别 " "年龄 " "电话 " "家庭住址\n");
	while (tmp)
	{
		
		printf(" %d %s  %s  %d  %s  %s ",i++, tmp->x.name,
			tmp->x.gender,
			tmp->x.age, tmp->x.tel,
			tmp->x.addr);
		tmp = tmp->next;
		printf("\n");
	}
	
}
//删除通讯录数据
void DelContact(Contact** con)
{
	assert(con && *con);
	char name[NAME_MAX] = { 0 };
	Contact* pcur = *con;
	printf("请输入要删除的联系人姓名:>\n");
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			SLLErase(con, pcur);
			break;
		}
		else
		{
			pcur = pcur->next;
		}	
	}
	if (flag == 1)
	{
		printf("删除联系人成功!\n");
	}
	else
	{
		printf("要删除的联系人不存在\n");
	}
	
}
//查找通讯录数据
void FindContact(Contact* con)
{
	assert(con);
	char name[NAME_MAX] = { 0 };
	Contact* pcur = con;
	printf("请输入要查找的联系人姓名:>\n");
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			break;
		}
		else
		{
			pcur = pcur->next;
		}
	}
	if (flag == 1)
	{
		printf("%s的信息如下:>\n", pcur->x.name);
		printf( "姓名 " "性别 " "年龄 " "电话 " "家庭住址\n");
		printf(" %s  %s  %d  %s  %s ", pcur->x.name,
			pcur->x.gender,
			pcur->x.age, pcur->x.tel,
			pcur->x.addr);
		printf("\n");
	}
	else
	{
		printf("%s不在通讯录中\n",name);
	}
}
//修改通讯录数据
void ModifyContact(Contact** con)
{
	assert(con&&*con);
	printf("请输入要修改的联系人姓名:\n");
	char name[NAME_MAX] = { 0 };

	Contact* pcur = *con;
	scanf("%s", name);
	int flag = 0;
	while (pcur)
	{
		if (strcmp(name, pcur->x.name) == 0)
		{
			flag = 1;
			break;
		}
		else
		{
			pcur = pcur->next;
		}
	}
	if (flag == 1)
	{
		printf("请输入要修改的联系人姓名:>\n");
		scanf("%s", pcur->x.name);
		printf("请输入要修改的联系人性别:>\n");
		scanf("%s", pcur->x.gender);
		printf("请输入要修改的联系人年龄:>\n");
		scanf("%d", &pcur->x.age);
		printf("请输入要修改的联系人电话:>\n");
		scanf("%s", pcur->x.tel);
		printf("请输入要修改的联系人家庭住址:>\n");
		scanf("%s", pcur->x.addr);
		printf("修改成功!\n");
		printf("\n");
	}
	else
	{
		printf("%s不在通讯录中\n", name);
	}
}
//销毁通讯录数据
void DestroyContact(Contact** con)
{
	SLLDestroy(con);
}

test.c文件逻辑实现

#include"SingleLinkedList.h"
void test01()
{
	Contact* con;
	InitContact(&con);
	AddContact(&con);
	AddContact(&con);
	//DelContact(&con);
	//FindContact(con);
	//ModifyContact(&con);
	ShowContact(con);
    DestroyContact(&con);
	ShowContact(con);
}


int main()
{
	test01();

	return 0;
}

定义一个test01函数将各类通讯录接口测试一下,没有问题,我们开始写通讯录调用逻辑及菜单打印的实现:

menu()菜单函数实现

void menu()
{
	printf("          ---------我的通讯录---------\n");
	printf("          |1.添加联系人||2.删除联系人|\n");
	printf("          ----------------------------\n");
	printf("          |3.查找联系人||4.修改联系人|\n");
	printf("          ----------------------------\n");
	printf("          |5.展示联系人||0.退出      |\n");
	printf("          ----------------------------\n");
}

实现效果:

main()主函数逻辑实现

int main()
{
	int input = 0;
	Contact* con;
	InitContact(&con);
	do
	{
		menu();
		printf("请选择:>\n");
		scanf("%d", &input);
		system("cls");
		switch (input)
		{
		case EXIT:
			exit(0);
		case ADD:
			AddContact(&con);
			system("pause");
			system("cls");
			break;
		case ERASE:
			DelContact(&con);
			system("pause");
			system("cls");
			break;
		case FIND:
			FindContact(con);
			system("pause");
			system("cls");
			break;
		case MODIFY:
			ModifyContact(&con);
			system("pause");
			system("cls");
			break;
		case SHOW:
			ShowContact(con);
			system("pause");
			system("cls");
			break;
		}
	} while (input);
	DestroyContact(&con);
	return 0;
}

添加system("pause");和system("cls");程序暂停和程序清理语句,让各类接口衔接连贯,最后循环结束,将通讯录销毁,程序return 0正常退出。

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

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

相关文章

优思学院|六西格玛绿带重不重要?绿带的报考条件是什么?

在最原始的六西格玛管理之中&#xff0c;六西格玛的最主要角色就只有六西格玛黑带&#xff0c;这是Mikel Harry所命名的&#xff0c;意思是一个对六西格玛方法十分熟练的人。 然而&#xff0c;六西格玛黑带也要靠团队才能完成工作&#xff0c;如果团队中只有黑带了解六西格玛流…

AcWing算法提高课笔记——数字三角形

本文给出了几道数字三角形模型的题解。 数字三角形模型通常给定一个矩阵&#xff0c;从矩阵的左上角走到右下角&#xff0c;每次只能向右走或者向下走&#xff0c;求最大值或者最小值。 这种问题可以用f[i, j]来表示从[1, 1]走到[i, j]处的Max\Min&#xff0c;有状态转移方程…

minikube 实践练习4 - 滚动更新

1. 应用版本更新 #查看image kubectl describe pods#设置应用的image为新版本 v1 -> v2 kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcampdocker.io/jocatalin/kubernetes-bootcamp:v2#验证更新结果 export NODE_PORT"$(kubectl get services/…

在Moodle中集成ONLYOFFICE:学习管理+文档功能全面指南

一、引言 随着在线教育的发展&#xff0c;Moodle作为领先的开源学习管理系统&#xff0c;其灵活性和可扩展性为教育工作者提供了丰富的功能。而ONLYOFFICE文档服务器的加入&#xff0c;更是为Moodle用户带来了无缝的文档处理与协作体验。本文将详细指导您如何在Moodle中深度集成…

【数据结构】二叉树篇

文章目录 1.二叉树链式结构功能的实现1.1 前置说明1.2 二叉树的遍历1.2.1 前序、中序以及后序遍历1.2.2 层序遍历 1.3 节点个数以及高度差1.3.1 二叉树的节点个数1.3.2 二叉树叶子节点个数1.3.3 二叉树第K层节点个数1.3.4 二叉树树查找值为x的节点1.3.5 二叉树的销毁 1.4 代码整…

RAG 工具和框架介绍: Haystack、 LangChain 和 LlamaIndex

Haystack、 LangChain 和 LlamaIndex&#xff0c;以及这些工具是如何让我们轻松地构建 RAG 应用程序的&#xff1f; 我们将重点关注以下内容&#xff1a; HaystackLangChainLlamaIndex 增强LLM 那么&#xff0c;为什么会有这些工具存在呢&#xff1f;如你所知&#xff0c;C…

LVS学习与练习

LVS (Linux Virtual Server) 是一种高性能的负载均衡解决方案&#xff0c;它基于 Linux 内核实现。LVS 可以用来构建高可用性和高性能的 Web 服务器集群。LVS 支持多种负载均衡算法和模式&#xff0c;可以有效地分发网络请求到多台后端服务器上。 LVS 的主要组成部分 1. Direc…

InternLM+LlamaIndex RAG 实践

本期实战训练营介绍了使用书生葡语的InternLM和LlamaIndex框架进行RAG项目的实践。内容分为三个部分&#xff1a;回顾InternLM的发展历程&#xff0c;介绍RAG的基本概念和应用&#xff0c;以及实践一个RAG项目。RAG技术结合了检索与生成&#xff0c;通过外部知识库增强大模型的…

开源Docker图形化管理工具DockerUI

DockerUI 是一个 Web 用户界面&#xff0c;它允许用户通过浏览器与 Docker 守护进程进行交互&#xff0c;而无需在命令行中执行 Docker 命令。它为 Docker 容器、镜像、网络等提供了直观的图形界面管理。然而&#xff0c;需要注意的是&#xff0c;DockerUI 已经不再是最流行的 …

领先数年!这款ERP系统已成制造业趋势!

企业数字化转型的趋势不可阻挡&#xff0c;在全球化竞争的背景下&#xff0c;市场变化迅速&#xff0c;客户需求日益多样化&#xff0c;企业需要更加敏捷地响应市场变化&#xff0c;提高生产效率和产品质量&#xff0c;以满足客户的需求。 而在这一转型过程中&#xff0c;ERP …

怎么直接在PDF上修改内容?随心编辑PDF内容

PDF(Portable Document Format)作为一种专用于阅读而非编辑的文档格式&#xff0c;其设计的核心目的是保持文档格式的一致性&#xff0c;确保文档在不同平台和设备上都能以相同的布局和格式呈现。然而&#xff0c;在实际工作和生活中&#xff0c;我们经常需要对PDF文档进行编辑…

Python编写Word文档

目录 1. 创建word文档 2. 添加标题、居中、字体16大小 3. 添加标题一 4. 添加一段话并设置字体颜色 5. 换页 6. 插入表格 1. 创建word文档 from docx import Documentdoc Document() 2. 添加标题、居中、字体16大小 from docx.shared import Pt from docx.enum.text i…

AT360-6T杭州中科微授时模块场景应用

AT360-6T是一款高性能多系统卫星定位授时模块&#xff0c;基于自主研发的北斗多系统 SOC 芯片&#xff0c;可以同时接收中国的 BDS(北斗二号和北斗三号)、美国的 GPS、俄罗斯的 GLONASS、欧盟的 GALILEO 和日本的 QZSS 等多个卫星导航系统的 GNSS 信号来实现多系统联合定位授时…

实用篇 | 服务器查看监听端口的程序

对于一些程序员最痛苦的是接手一些“二手系统“&#xff0c; 由于年久失修&#xff0c; 加上裁员离职&#xff0c;系统文档不完善等原因&#xff0c; 只留下服务器配置和代码。 接手人&#xff0c;只能对着这些仅存的代码和服务器硬刚&#xff0c; 对服务器硬刚的第一步&#x…

高盛推荐包装食品行业两大首选股票

市场动荡与食品行业的防御性 近期市场的剧烈波动、7月份疲弱的就业报告以及对美联储可能降息的预期&#xff0c;引发了人们对经济衰退的担忧。尽管市场在本周有所反弹&#xff0c;投资者们开始调整策略&#xff0c;寻求更具防御性的投资方向。在这种背景下&#xff0c;包装食品…

Vue2移动端(H5项目)项目基于vant实现select单选(支持搜索、回显、自定义下拉label展示功能)

一 最终效果 二、参数配置 1、代码示例&#xff1a; <t-selectv-model"formData.materialNo"valueKey"materialNo"showLabel"materialName"labelKey"label"label"判定品级"input-align"right"placeholder&qu…

Google Earth Engine(GEE)——1986-2021年黄河入海口区域的逐年影像展示案例分析,并加载可以分享的URL链接

函数: size() Returns the number of elements in the collection. 返回集合中元素的数量。 Arguments: this:collection (FeatureCollection): The collection to count. Returns: Integer 融合影像可以一个接一个进行融合 merge(collection2) Merges two image co…

CAXA快捷键

1.左下角处选择导航&#xff0c;快捷键F6可以切换 2.自定义快捷键 鼠标右键点击菜单栏空白处 点击自定义&#xff0c;便可以修改快捷键

Leetcode—1239. 串联字符串的最大长度【中等】(unordered_set)

2024每日刷题&#xff08;155&#xff09; Leetcode—1239. 串联字符串的最大长度 实现代码 class Solution { public:bool charSet(string & s) {unordered_set<char> charSet(s.begin(), s.end());// true表示有重复// false表示唯一return s.size() ! charSet.s…

HTML原生手搓询盘

效果展示&#xff1a; 1、PC布局&#xff1a; 2、移动布局&#xff1a; 3、交互展示&#xff1a; 1、HTML代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"wid…