1.门锁_STM32_用户功能

概述

需求来源:

在一些没有前台的那种公寓酒店订房的时候,就会有一个人加我微信,之后给我发一个房间号,和密码。这需要一种用户的功能来控制门锁的密码。同时也有一个房间好几个人合租的情况,它们都是多个用户共享一把锁,当用户退房后,这个用户在系统中就被删除。

设计这个用户功能,可以更加方便的管理用户的密码、修改相应权限等。

设置整体思路:

该用户管理功能的实现基于链表。一切基于C语言链表的增删改查。结构框图如下:

首先我们需要把用户的信息用结构体的形式抽象出来,之后每一个结构体就代表一个用户。

然后需要创建一个不可被删除的头结点,这个用户称为root用户,就是整个用户系统的管理员。

之后每添加一个用户,就在root用户之后进行链接即可。

相关函数功能:

  • 初始化用户系统:pUsr init_user(void);
  • 创建新用户:pUsr create_user(char* name,char* phone);
  • 添加用户:int add_user(pUsr newUser);
  • 删除用户:int del_user(char* name);
  • 查询用户:pUsr search_user(char* name);
  • 检查用户密码:int check_passwd(char* name,char* oldPasswd);

程序实现

0、定义用户结构体

一个用户具有用户名、密码、绑定的手机这三种属性,将其定义为一个结构体进行管理。定义如下

typedef struct user{
	char* name;       //用户名
	char passwd[7];   //正确密码
	char phone[12];   //绑定手机号
	struct user* pNext;
}Usr,*pUsr;

在这个结构体中,规定了密码为6位,绑定的电话号码为11位。 

这个用户定义的框架是链表形式,之后将以链表的增删改查为基础对其进行管理。

同时,在.c文件中定义了两个静态全局变量,用于存放用户系统的头结点和尾结点位置:

static pUsr gpUserTail = NULL;//尾结点指针
static pUsr gpUserHead = NULL;//头结点指针

1、初始化用户系统

代码需求:

  • 初始化用户系统就是创建root用户作为头结点,这个root用户名称为root,密码为123456。
  • root用户是禁止删除的用户,代表整个用户系统的存在,之后创建的新用户会链接到root之后。

代码实现步骤:

  • 使用malloc开辟用户空间和用户名空间。
  • 使用strcpy对用户名、密码进行赋值,即:初始化用户信息。

具体代码实现如下:

/*
 * pUsr init_user:初始化用户列表,创建root用户
 *                root用户名为root,密码为000000
 * @ret  NULL--err other--success
 * */
pUsr init_user(void){

	//1.开辟空间,创建root用户结点
	//1.1 头指针,尾指针都指向这个结点
	gpUserTail = (pUsr)malloc(sizeof(Usr));
	gpUserHead = gpUserTail;
	if(gpUserTail == NULL){
		printf("init user err\n");
		return NULL;
	}
	//1.2 开辟名字空间,用户名为root
	gpUserHead->name = (char*)malloc(sizeof(char)*(strlen("root")+1));
	if(gpUserHead->name == NULL){
		printf("name malloc err\n");
		return NULL;
	}
	//2.初始化用户
	//2.1 清空
	memset(gpUserHead->name,'0',sizeof(strlen("root")+1));
	memset(gpUserHead->passwd,'0',sizeof(gpUserHead->passwd));
	memset(gpUserHead->phone,'0',sizeof(gpUserHead->phone));
	//2.2 赋值
	strcpy(gpUserHead->name,"root");
	strcpy(gpUserHead->passwd,"123456");
	gpUserHead->pNext = NULL;
	return gpUserTail;
}

2、创建新用户

代码需求:

  • 创建新用户,设置初始密码为000000,用户名和电话由函数外部传入。

代码实现步骤:

  • 与初始化用户系统类似,只是初始化的用户信息不同。
  • 需要对用户名重复进行判断,不允许出现用户名重复的情况。
  • 需要对传入的电话进行判断,保证电话号码长度正确。

具体代码实现如下:

/*
 * create_usr:创建一个用户,初始密码000000
 * param name : 用户名
 * param phone: 绑定手机号
 * @ret  NULL--err  other--用户结构体的指针
 * */
pUsr create_user(char* name,char* phone){
	pUsr pUser = NULL;
	//1.参数有效性判断
	//1.1 用户名重复判断
	if(search_user(name) != NULL){
		printf("user name exsit\n");
		return NULL;
	}
	//1.2 电话长度判断
	if(strlen(phone)  != 11){
		printf("phone length err\n");
		return NULL;
	}
	//2.申请空间
	//2.1 开辟用户空间
	pUser = (pUsr)malloc(sizeof(Usr));
	if(pUser == NULL){
		printf("pUser malloc err\n");
		return NULL;
	}
	//2.2 开辟名字空间
	pUser->name = (char*)malloc(sizeof(char)*(strlen(name)+1));
	if(pUser->name == NULL){
		printf("name malloc err\n");
		return NULL;
	}
	//3.初始化
	//3.1 清空
	memset(pUser->name,'0',sizeof(strlen(name)+1));
	memset(pUser->passwd,'0',sizeof(pUser->passwd));
	memset(pUser->phone,'0',sizeof(pUser->phone));
	//3.2 赋值
	strcpy(pUser->name,name);
	strcpy(pUser->passwd,"000000");
	strcpy(pUser->phone,phone);
	pUser->pNext = NULL;
	return pUser;
}

3、添加用户

添加用户在这里设计的就是在尾部插入用户即可。

注意:在尾部插入后,尾部全局变量指针需要去更新。

具体代码实现如下:

/*
 * add_user:添加用户
 * param newUser:新用户结点
 * @ret  -1--err  0--success
 * */
int add_user(pUsr newUser){
	pUsr point = gpUserTail;//尾部结点
	//1.判断结点非空
	if(newUser == NULL){
		printf("newUser is NULL\n");
		return -1;
	}
	//2.开始插入
	point->pNext = newUser;
	gpUserTail = newUser;//尾插后更新尾部的指针指向
	return 0;
}

4、删除用户

代码需求:

  • 删除用户就是链表的删除,这里规定头部不能被删除。

代码实现分析:

  • 首先找到链表位置并保存链表前驱的位置,之后开始删除链表
  • 这里需要分三种情况:删除的是头、删除的是尾、删除的是中间                                            头结点禁止删除、尾结点删除后尾部指针需要更新,中间删除就是正常的链表删除。 

具体代码实现如下:

/*
 * del_user:删除指定的用户
 * param name:要删除的用户名
 * @ret  -1--err  0--success
 * */
int del_user(char* name){
	
	pUsr point = gpUserHead;
	pUsr pTmp = NULL;//pTmp存储上一个结点,头结点的上一个结点为NULL
	//1.判断结点非空
	if(name == NULL){
		printf("name is NULL\n");
		return -1;
	}
	//2.找到用户所在的结点
	while(point!=NULL){
		if(strcmp(point->name,name) == 0){
			break;
		}
		pTmp = point;//上一个结点
		point = point->pNext;
	}
	//3.开始删除
	//3.1 找不到,代表以及删除了
	if(point == NULL){
		printf("user has del\n");
		return 0;
	}
	//3.2 找到了,开始删除
	if(strcmp(point->name,"root") == 0){//头禁止删除
		printf("root cannot del\n");
		return 0;
	}
	if(point->pNext == NULL){//尾巴删除后指针改变
		gpUserTail = pTmp;
	}
	pTmp->pNext = point->pNext;
	free(point);
	point = NULL;
	return 0;	
}

5、查询用户

查询用户就是遍历整个链表,查找到名称相同的用户。

具体代码实现如下:

/*
 * search_user:按名字寻找用户结点
 * param name:要寻找的用户的名字
 * @ret  NULL--not find  other--第一个结点首地址
 * */
pUsr search_user(char* name){
	
	pUsr point = gpUserHead;
	//1.参数有效性判断
	if(name == NULL){
		printf("name is NULL\n");
		return NULL;
	}
	//2.遍历寻找
	while(point!=NULL){
		//printf("Debug:point->name = %s\n",point->name);
		if(strcmp(point->name,name) == 0){
			break;
		}
		point = point->pNext;
	}
	if(point == NULL){
		//printf("not find\n");
	}
	return point;
}

6、检查用户密码

检查用户密码,就是找到指定的用户,比较一下它的密码和传入的密码是否相同。

具体代码实现如下:

/*
 * check_passwd:验证原密码正确性
 * param name:用户名
 * param oldPasswd:原密码
 * @ret  -1--err  0--passwd right
 * */
int check_passwd(char* name,char* oldPasswd){
	pUsr pUser = NULL;
	//1.判断参数有效性
	//1.1 指针非空判断
	if(name == NULL || oldPasswd == NULL){
		printf("param err\n");
		return -1;
	}
	//1.2 密码长度合法判断
	if(strlen(oldPasswd) != 6){
		printf("passwd len err\n");
		return -1;
	}
	//2.找到用户所在的结点
	pUser = search_user(name);
	if(pUser == NULL){
		printf("user not exsit\n");
		return -1;
	}
	//3.验证原密码正确性
	if(strcmp(pUser->passwd,oldPasswd) != 0){
		printf("oldPasswd err\n");
		return -1;
	}else{
		printf("oldPasswd right\n");
		return 0;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值