资源描述
《我的第一个管理系统》
这是我的第一个人员签到签出管理系统。
A. 可以实现的功能
1. 用户注册(只要内存足够可以实现无穷多个用户注册)
2. 用户签到 记录用户员工是否迟到
3. 用户签退 记录用户员工是否早退
4. 员工出勤情况查询(涉及总共上班天数,迟到次数,早退次数)
B.我认为程序比较好的地方
1.假如内存可以系统可以让无穷多个用户实现注册。
2.可以让用户在任意时刻签到或者签退,并且假如内存足够可以实现无穷多次的签到或者签退,并且完整记录信息。
3.用户注册时候提供了注册名不会反复的功能,假如反复提醒用户重新拟定注册名。
4.在输入注册密码时让用户两次输入密码比较是否同样,假如不同样则提醒用户密码不一致请重新输入。
5.所有密码在输入时所有以*回显,保证密码不会泄露。
6.每一步都有完整的提醒指导用户操作,对每一种也许发生的情况都做了相应的解决(当然还会有我没有想到的情况)。
7.本程序是用纯C编写出来的,依靠的是链表指针操作,看起来不是很容易。
C.程序的重要思想
1.不用C++里面的类,完全用结构体来代替。
2.先创建一个用户emp结构体,用来作为横向链表的节点,存储用户名,用户密码等基本信息。
3.再创建一个day签到签退结构体用来作为竖向节点,用来记录用户天天签到情况。
4.总体就是一个用户就是一个链表,每注册一个用户就在横向链表里插入一个节点记录用户名等基本信息,然后就是每个横向节点又作为每个用户签到链表的头结点,这样签到一次就在该用户相应的横节点下插入一个节点记录该用户签到情况。
D.程序的局限性之处
1.没有美丽的界面,看起来不爽。
2.没有提供开除员工的取消用户注册的操作(其实也比较好实现,再多加一个函数就可以解决)。(以实现)
3.程序中用到大量的goto语句,这里不提倡使用。
4.记录数据不是十分充足,但是随时可以扩充。
5.假如程序意外停止,那么所有数据所有丢失,所以本系统不是用来用的,是用来看的。
6.程序反复代码有好多,其实可以精简。
7《此程序最终可以实现回车重新输入密码》
《所有功能都实现了哈哈哈哈哈》
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct days
{
int stime;//上班时间
int gotime;//下班时间
char islate;//是否迟到Y为迟到N为没有迟到
char isgoearly;//是否早退
days *next;
}day;
typedef struct emplore
{
char join[20];//用户名
char sec[20];//用户密码
emplore *next;
day *next1;
}emp;
int findjoin(emp *head,const char *name)//通过用户名查找
{
char C;
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
printf("请输入用户密码:\n");
return 1;//查找到相应的用户名
}
else
{
head=head->next;
}
}
if(head==NULL)
{
printf("此用户名不存在,您现在需要注册吗?Y注册,N不注册\n");
C=getche();
//scanf("%c",&C);
if(C=='Y')
return 2;//需要注册
else
return 3;//不需要注册
}
return 0;
}
int insert1(emp *&head,char *name,char *mima1)//用户注册时候需要的链表????注意head要用引用哦!
{
emp *p;
p=(emp*)malloc(sizeof(emp));
if(p==NULL)
{
printf("注册失败\n");
return 0;
}
else
printf("\n恭喜您注册成功\n");
strcpy(p->join,name);
strcpy(p->sec,mima1);
p->next=head;
p->next1=NULL;//重要的一步一定要初始化为NULL方便标记
head=p;
return 0;
}
int findmima(emp *head,const char *name,const char *mima1)//一定是在有用户名的情况下
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
if(strcmp(head->sec,mima1)==0)
{
printf("\n密码对的请选择签到还是签退:\ne签到l签退t退出系统\n");//提供选项让用户选择签到还是签退
return 0;
}
else
{
printf("\n密码错误请重新输入:");
return 1;
}
}
else
head=head->next;
}
return 0;
}
int cometime(day *&p)//输入签早到信息并且解决信息
{
printf("请输入签早届时间,相信你是诚实的哦\n");
scanf("%d",&(p->stime));//这个地方一定要注意,这不是C++是纯C一定要注意啊
if(p->stime>8)
p->isgoearly='Y';
else
p->isgoearly='N';
p->islate='N';//实现分开解决的必要条件
printf("您已经完毕签到\n");
return 0;
}
int goouttime(day *&p)//输入签退信息并且解决信息
{
printf("\n请输入签退时间,相信你是诚实的哦\n");
scanf("%d",&(p->gotime));
if(p->gotime<18)
p->islate='Y';
else
p->islate='N';
p->isgoearly='N';//实现分开解决的必要条件
printf("您已经完毕签退\n");
return 0;
}
int insert2(emp *head,char *name,day *p)//找到本用户的头结点并插入,这里找到的head就是该用户的头结点
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
p->next=head->next1;
head->next1=p;
return 0;
}
head=head->next;
}
return 0;
}
int findrec(emp *head,char *name)//查找用户信息
{
int rday=0,rlate=0,rearly=0;
day *p=NULL;
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
p=head->next1;
while(p!=NULL)
{
rday++;//记录一共签到多少次
if(p->isgoearly=='Y')
rearly++;
if(p->islate=='Y')
rlate++;
p=p->next;
}
printf("总共有记录的条数:%d\n",rday);
printf("总共有记录迟到的次数:%d\n",rlate);
printf("总共有记录早退的次数:%d\n",rearly);
return 0;//这一步是必要的哦
}
head=head->next;//这一步不要忘掉啊
}
return 0;
}
int findname(emp *head,char *name)//查找用户信息
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
return 1;
head=head->next;
}
if(head==NULL)
return 0;
return 0;
}
int delete_q(emp *p)//删除本人尚有其所有的记录
{
day *p1,*p2;
if(p==NULL)
return 0;
p1=p->next1;
free(p);
while(p1!=NULL)
{
p2=p1;
p1=p1->next;
free(p2);
}
return 0;
}
int goout(emp *&p,char *name,char *mima)//用户注销,返回一注销成功删除所有记录
{
emp *p1;
if(p==NULL)
{
printf("\n用户名不存在或密码错误\n");
return 0;
}
if(p->next==NULL)//一定不是不能操作
{
if(strcmp(p->join,name)==0&&strcmp(p->sec,mima)==0)
{
delete_q(p);
p=NULL;
printf("注销成功");
return 1;
}
else
{
printf("密码错误,注销失败");
return 0;
}
}
if(strcmp(p->join,name)==0)
{
if(strcmp(p->next->join,mima)!=0)
{
p1=p;
p=p->next;
delete_q(p1);
//printf("册成功yue");
return 1;
}
}
p1=p;
while(p1->next!=NULL)
{
if(strcmp(p1->next->join,name)==0&&strcmp(p1->next->sec,mima)==0)
{
//printf("%s %s",p1->next->sec,mima);
p1->next=p1->next->next;
delete_q(p1->next);
printf("注销成功");
return 1;
}
p1=p1->next;
}
printf("注销失败\n");
return 0;
}
int change_mima(emp *p,char *name)
{
char a[20],b[20];
if(findname(p,name)==0)
{
printf("\n该用户名不存在");
return 0;
}
while(p!=NULL)
{
if(int(strcmp(p->join,name))==0)
{
printf("请输入用户密码");
scanf("%s",a);
if(strcmp(p->sec,a)!=0)
{
printf("密码错误");
return 0;
}
else
{ loop7:
printf("请输入您的新密码:\n");
scanf("%s",a);
printf("请重新输入您的新密码:\n");
scanf("%s",b);
if(strcmp(a,b)!=0)
{
printf("两次新密码不一致请重新输入:");
goto loop7;
}
else
{
strcpy(p->sec,a);
printf("恭喜您密码更改成功");
return 1;
}
}
}
}
return 0;
}
/////////////////////////////////////////////////////////////////
int main()
{
printf("+_+欢迎进入-_-欣欣-_-自动签到系统+_+\n");
emp *head1=NULL;
char name[20],mima[20],mimayangli[20],biao,kk;
day *p1=NULL;
int pp=0,pp1=0,i=0;
loop:
pp=0;
pp1=0;
i=0;
printf("\n按任意键进入系统:\n");
getch();//暂停
loop6:
printf("请选择操作:\nA查询,B签到,C注册,D退出,E用户注销,G更改用户密码(不区分大小写)\n");
biao=getche();
if(biao=='G'||biao=='g')
{
printf("\n请输入您要更改密码的用户名\n");
scanf("%s",name);
change_mima(head1,name);
goto loop6;
}
if(biao=='e'||biao=='E')
{
printf("\n请输入您的用户名:\n");
scanf("%s",name);
printf("请输入密码:\n");
i=0;
while(kk=getch())
{
if(kk=='\r')
break;
if(kk=='\b')
{
i--;
printf("\b ");
printf("\b");
if(i<=0)
i=0;
continue;
}
printf("*");
mima[i]=kk;
i++;
}
mima[i]='\0';
if(goout(head1,name,mima)==1)//用户注销
printf("\n用户注销成功,感谢您近期的使用\n");
goto loop6;
}
if(biao=='d'||biao=='D')
{
printf("\n系统已近退出请按提醒操作");
goto loop;
}
if(biao=='a'||biao=='A')
{
printf("\n现在您正处在查询状态中\n");
goto loop3;
}
if(biao=='c'||biao=='C')
goto loop4;
printf("\n请输入用户名:\n");
scanf("%s",name);
pp=findjoin(head1,name);
if(pp==2)//假如返回值是2那么就用户注册
{
loop4:
printf("\n请输入您的注册名:\n");
scanf("%s",name);
if(findname(head1 , name)==1)
{
printf("此用户名已存在请重新拟定您的注册名");
goto loop4;
}
loop5:
printf("请输入您的注册密码 :\n");
i=0;
while(kk=getch())
{
if(kk=='\r')
break;
if(kk=='\b')
{
i--;
printf("\b ");
printf("\b");
if(i<=0)
i=0;
continue;
}
printf("*");
mima[i]=kk;
i++;
}
mima[i]='\0';
printf("\n请再次输入您的注册密码:\n");
i=0;
while(kk=getch())
{
if(kk=='\r')
break;
if(kk=='\b')
{
i--;
printf("\b ");
printf("\b");
if(i<=0)
i=0;
continue;
}
printf("*");
mimayangli[i]=kk;
i++;
}
mimayangli[i]='\0';
if(strcmp(mima,mimayangli)==0)
{
insert1(head1,name,mima);
printf("请继续选择您需要的操作\n");
goto loop6;
}
else
{
printf("\n两次密码输入不同请重新输入");
goto loop5;
}
}
if(pp==3)
goto loop;//这位用户选择退出从头开始
if(pp==1)//假如返回值是1那么就输入密码
{
loop1:
i=0;
while(kk=getch())
{
if(kk=='\r')////
break;
if(kk=='\b')
{
i--;
printf("\b ");
printf("\b");
if(i<=0)
i=0;
continue;
}
printf("*");
mima[i]=kk;
i++;
}mima[i]='\0';
}
pp1=findmima(head1,name,mima);
if(pp1==1)//假如返回值是一的话那么就要用户重新输入密码跳到输入密码处
goto loop1;
//这里就是把每一次签到或签退的情况分开解决
if(pp1==0)//在密码这对的的情况下提醒用户操作
{
p1=(day*)malloc(sizeof(day));
//p1->next=NULL;
biao=getch();
if(biao=='t')
goto loop;//这一步用户选择退出程序跳转到开头供下一位用户选择使用
if(biao=='e')//
cometime(p1);//这一步完毕签早到信息并判断了是否迟到
if(biao=='l')
goouttime(p1);//这一步完毕签退信息并判断了是否早退
insert2(head1,name,p1);//这一步完毕向头结点插入,每次插入都是最新的位置,这一步是必须的
}
printf("请重新选择操作或者选择退出\n");
goto loop6;
loop3:
printf("请输入您要查询的用户名:\n");
scanf("%s",name);
if(findname(head1,name)==1)//假如返回值是1那么就用户存在
{
findrec(head1,name);
}
else
{
printf("用户名错误或者该用户不存在请重新选择操作");
printf("\n");
goto loop6;
}
printf("查询已完毕请继续选择操作或者退出\n");
goto loop6;
return 0;
}
《此程序局限性》《下面有修改过的程序》
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct days
{
int stime;//上班时间
int gotime;//下班时间
char islate;//是否迟到Y为迟到N为没有迟到
char isgoearly;//是否早退
days *next;
}day;
typedef struct emplore
{
char join[20];//用户名
char sec[20];//用户密码
emplore *next;
day *next1;
}emp;
int findjoin(emp *head,const char *name)//通过用户名查找
{
char C;
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
printf("请输入用户密码(输入#表达密码输入结束):\n");
return 1;//查找到相应的用户名
}
else
{
head=head->next;
}
}
if(head==NULL)
{
printf("此用户名不存在,您现在需要注册吗?Y注册,N不注册\n");
C=getche();
//scanf("%c",&C);
if(C=='Y')
return 2;//需要注册
else
return 3;//不需要注册
}
return 0;
}
int insert1(emp *&head,char *name,char *mima1)//用户注册时候需要的链表????注意head要用引用哦!
{
emp *p;
p=(emp*)malloc(sizeof(emp));
if(p==NULL)
{
printf("注册失败\n");
return 0;
}
else
printf("\n恭喜您注册成功\n");
strcpy(p->join,name);
strcpy(p->sec,mima1);
p->next=head;
p->next1=NULL;//重要的一步一定要初始化为NULL方便标记
head=p;
return 0;
}
int findmima(emp *head,const char *name,const char *mima1)//一定是在有用户名的情况下
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
if(strcmp(head->sec,mima1)==0)
{
printf("\n密码对的请选择签到还是签退:\ne签到l签退t退出系统\n");//提供选项让用户选择签到还是签退
return 0;
}
else
{
printf("\n密码错误请重新输入:");
return 1;
}
}
else
head=head->next;
}
return 0;
}
int cometime(day *&p)//输入签早到信息并且解决信息
{
printf("请输入签早届时间,相信你是诚实的哦\n");
scanf("%d",&(p->stime));//这个地方一定要注意,这不是C++是纯C一定要注意啊
if(p->stime>8)
p->isgoearly='Y';
else
p->isgoearly='N';
p->islate='N';//实现分开解决的必要条件
printf("您已经完毕签到\n");
return 0;
}
int goouttime(day *&p)//输入签退信息并且解决信息
{
printf("\n请输入签退时间,相信你是诚实的哦\n");
scanf("%d",&(p->gotime));
if(p->gotime<18)
p->islate='Y';
else
p->islate='N';
p->isgoearly='N';//实现分开解决的必要条件
printf("您已经完毕签退\n");
return 0;
}
int insert2(emp *head,char *name,day *p)//找到本用户的头结点并插入,这里找到的head就是该用户的头结点
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
p->next=head->next1;
head->next1=p;
return 0;
}
}
return 0;
}
int findrec(emp *head,char *name)//查找用户信息
{
int rday=0,rlate=0,rearly=0;
day *p=NULL;
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
p=head->next1;
while(p!=NULL)
{
rday++;//记录一共签到多少次
if(p->isgoearly=='Y')
rearly++;
if(p->islate=='Y')
rlate++;
p=p->next;
}
printf("总共有记录的条数:%d\n",rday);
printf("总共有记录迟到的次数:%d\n",rlate);
printf("总共有记录早退的次数:%d\n",rearly);
return 0;//这一步是必要的哦
}
head=head->next;//这一步不要忘掉啊
}
return 0;
}
int findname(emp *head,char *name)//查找用户信息
{
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
return 1;
head=head->next;
}
if(head==NULL)
return 0;
return 0;
}
/////////////////////////////////////////////////////////////////
int main()
{
printf("+_+欢迎进入-_-欣欣-_-自动签到系统+_+\n");
emp *head1=NULL;
char name[20],mima[20],mimayangli[20],biao,kk;
day *p1=NULL;
int pp=0,pp1=0,i=0;
loop:
pp=0;
pp1=0;
i=0;
printf("\n按任意键进入系统:\n");
getch();//暂停
printf("请选择操作:A查询,B签到,C注册,D退出(不区分大小写)\n");
biao=getche();
if(biao=='d'||biao=='D')
{
printf("\n系统已近退出请按提醒操作");
goto loop;
}
if(biao=='a'||biao=='A')
goto loop3;
if(biao=='c'||biao=='C')
goto loop4;
printf("\n请输入用户名:\n");
scanf("%s",name);
pp=findjoin(head1,name);
if(pp==2)//假如返回值是2那么就用户注册
{
loop4:
printf("\n请输入您的注册名:\n");
scanf("%s",name);
if(findname(head1 , name)==1)
{
printf("此用户名已存在请重新拟定您的注册名");
goto loop4;
}
loop5:
printf("请输入您的注册密码(输入到#表达密码输入完毕):\n");
i=0;
while(kk=getch())
{
if(kk=='#')
break;
printf("*");
mima[i]=kk;
i++;
}
mima[i]='\0';
printf("\n请再次输入您的注册密码(输入到#表达密码输入完毕):\n");
i=0;
while(kk=getch())
{
if(kk=='#')
break;
printf("*");
mimayangli[i]=kk;
i++;
}
mimayangli[i]='\0';
if(strcmp(mima,mimayangli)==0)
{
insert1(head1,name,mima);
printf("系统已经退出,想继续进入系统请重新开始\n");
goto loop;
}
else
{
printf("\n两次密码输入不同请重新输入");
goto loop5;
}
}
if(pp==3)
goto loop;//这位用户选择退出从头开始
if(pp==1)//假如返回值是1那么就输入密码
{
loop1:
i=0;
while(kk=getch())
{
if(kk=='#')
break;
printf("*");
mima[i]=kk;
i++;
}mima[i]='\0';
}
pp1=findmima(head1,name,mima);
if(pp1==1)//假如返回值是一的话那么就要用户重新输入密码跳到输入密码处
goto loop1;
//这里就是把每一次签到或签退的情况分开解决
if(pp1==0)//在密码这对的的情况下提醒用户操作
{
p1=(day*)malloc(sizeof(day));
//p1->next=NULL;
biao=getch();
if(biao=='t')
goto loop;//这一步用户选择退出程序跳转到开头供下一位用户选择使用
if(biao=='e')//
cometime(p1);//这一步完毕签早到信息并判断了是否迟到
if(biao=='l')
goouttime(p1);//这一步完毕签退信息并判断了是否早退
insert2(head1,name,p1);//这一步完毕向头结点插入,每次插入都是最新的位置,这一步是必须的
}
printf("系统已经退出,想继续进入系统请重新开始\n");
goto loop;
loop3:
printf("请输入用户名:\n");
scanf("%s",name);
if(findname(head1,name)==1)//假如返回值是1那么就用户存在
{
findrec(head1,name);
}
else
{
printf("用户名错误或者该用户不存在\n");
printf("系统已经退出,想继续进入系统请重新开始\n");
goto loop;
}
printf("系统已经退出,想继续进入系统请重新开始\n");
goto loop;
return 0;
}
《修改过的较好的程序》
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
typedef struct days
{
int stime;//上班时间
int gotime;//下班时间
char islate;//是否迟到Y为迟到N为没有迟到
char isgoearly;//是否早退
days *next;
}day;
typedef struct emplore
{
char join[20];//用户名
char sec[20];//用户密码
emplore *next;
day *next1;
}emp;
int findjoin(emp *head,const char *name)//通过用户名查找
{
char C;
while(head!=NULL)
{
if(int(strcmp(head->join,name))==0)
{
printf("请输入用户密码(输入#表达密码输入结束):\n");
return 1;//查找到相应的用户名
}
else
{
head=head->next;
}
}
if(head==NULL)
{
printf("此用户名不存在,您现在需要注册吗?Y注册,N不注册\n");
C=getche();
//scanf("%c",&C);
展开阅读全文