概述
需求来源:
在一些没有前台的那种公寓酒店订房的时候,就会有一个人加我微信,之后给我发一个房间号,和密码。这需要一种用户的功能来控制门锁的密码。同时也有一个房间好几个人合租的情况,它们都是多个用户共享一把锁,当用户退房后,这个用户在系统中就被删除。
设计这个用户功能,可以更加方便的管理用户的密码、修改相应权限等。
相关功能:
- 初始化用户系统: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位。
这个用户定义的框架是链表形式,之后将以链表的增删改查为基础对其进行管理。
1、初始化用户系统
这里采用创建一个冗余的头结点用户,这个用户的名称为head。之后这个结点禁止删除,添加的新用户会在这个结点之后,从而保证整个用户系统时刻存在。
具体代码实现如下:
static pUsr gpUserTail = NULL;
static pUsr gpUserHead = NULL;
/*
* pUsr init_user:初始化用户列表,创建头
* @ret NULL--err other--success
* */
pUsr init_user(void){
gpUserTail = (pUsr)malloc(sizeof(Usr));
gpUserHead = gpUserTail;
if(gpUserTail == NULL){
printf("init user err\n");
return NULL;
}
gpUserHead->name = (char*)malloc(sizeof(char)*(strlen("head")));
if(gpUserHead->name == NULL){
printf("name malloc err\n");
return NULL;
}
strcpy(gpUserHead->name,"head");
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.申请空间
pUser = (pUsr)malloc(sizeof(Usr));
if(pUser == NULL){
printf("pUser malloc err\n");
return NULL;
}
pUser->name = (char*)malloc(sizeof(char)*(strlen(name)+1));
if(pUser->name == NULL){
printf("name malloc err\n");
return NULL;
}
//2.用户名重复判断
if(search_user(name) != NULL){
printf("user name exsit\n");
return NULL;
}
//3.初始化
//memset(pUser,0,sizeof(Usr));
strcpy(pUser->name,name);
pUser->name[strlen(name)] = '\0';
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;
//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,"head") == 0){//头禁止删除
printf("head 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;
if(name == NULL){
printf("name is NULL\n");
return NULL;
}
//遍历寻找
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;
}
}