新增打卡机任务
主要增加结构体数组\数组排序的内容
to be continued …
#include <stdio.h> #include <stdlib.h> #include <ctime> #include <sys/time.h> #include <string.h> #include <unistd.h> //clock_t start_time1; //clock_t end_time1; #define WORKDAY 3 #define PROGRAMSTARTTIME 7.0 //程序开始时间为周一早上7点 #define WORKSTARTTIME 9 //上班时间 #define WORKENDTIME 18 //下班时间 //用于程序测试 #define HOUR_PER_SECOND 2 //测试时以2s表示一个小时 #define DAY_PER_HOUR 24 //测试时以24h表示一天 timeval program_start_time; timeval program_end_time; int date_count_hour=0,date_count_day = 0; struct Staff_msg{ char name[15]; char sex[7]; char phone[11]; char mail[20]; }; typedef struct Struct_Staff{ Staff_msg private_msg; char id[7]; timeval in_time; timeval out_time; double workhour_count = 0;//mytimer1(in_time,out_time); int late_count = 0;//迟到 int absence_count = 0;//缺勤 int leave_early_count = 0;//早退 int late_date[WORKDAY];//记录对应的时间 int absence_date[WORKDAY]; int leave_early_date[WORKDAY]; int check1 = 0;//正常上班打卡check int check2 = 0;//不正常上班打卡check int check3 = 0;//不正常下班打卡check int check4 = 0;//正常下班打卡check int check5 = 0;//弹性打卡check }SS; SS staff[20]; void log_in() { strcpy(staff[0].id,"123456"); strcpy(staff[0].private_msg.name,"张三"); strcpy(staff[1].id,"111111"); strcpy(staff[1].private_msg.name,"李四"); strcpy(staff[2].id,"122222"); strcpy(staff[2].private_msg.name,"王五"); } void printWorkMsg(SS staffx) { printf( "Staff id : %s\n", staffx.id); printf( "Average work time : %.2f\n",staffx.workhour_count/WORKDAY); printf( "Late : %d\n", staffx.late_count); printf( "Absence : %d\n", staffx.absence_count); printf( "Early Leave : %d\n\n", staffx.leave_early_count); } void printRewardList() { printf("奖励名单\n"); for(int i=0;i<3;i++) { if(staff[i].late_count == 0 && staff[i].leave_early_count == 0 && staff[i].absence_count == 0) { printf("%s获全勤奖\n",staff[i].private_msg.name); } } } SS *sortWorkTime(SS *staff) { SS *arr[20]; for(int t=0;t<20;t++) arr[t] = staff + t; for(int i = 0; i < 20; i++) { for(int j = 0; j < 20 - i; j++) { if(arr[j]->workhour_count > arr[j+1]->workhour_count) {// 相邻元素两两对比 SS *temp = arr[j+1]; arr[j+1] = arr[j]; arr[j] = temp; } } } return arr[0]; } void printPunishList() { printf("惩罚名单\n"); SS temp = *sortWorkTime(&staff[0]); for(int j=3;j>0;j--) printf("惩罚:%s,原因:\n",((&temp + j)->id)); } //计时函数clock() 经测试发现该计时方法不准 /* void mytimer(clock_t start_time1,clock_t end_time1) { start_time=clock(); //程序开始计时 int ans=0; for(int i=1;i<=1e8;i++) ans++; end_time=clock(); //程序结束用时 double total_time=(double)(end_time1-start_time1)/CLOCKS_PER_SEC; cout<<"Total time:"<<total_time<<"s"<<endl; //s为单位 cout<<"Total time:"<<total_time*1000<<"ms"<<endl; //ms为单位 //system("pause"); }; */ //计时函数gettimeofday double mytimer1(timeval start_time,timeval end_time) { //timeval start_time, end_time; //gettimeofday(&start_time, NULL); //gettimeofday(&end_time, NULL); double second = (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_usec - start_time.tv_usec)/1e6; //1秒一个小时,24小时一天 date_count_hour = second / HOUR_PER_SECOND; date_count_day = date_count_hour / DAY_PER_HOUR ; return date_count_hour; }; //判断编号是否符合规范 //及匹配到人to do int judge_Verification(char *p) { char s[7]={0}; strcpy(s,p); int i = strlen(s); int flag = 0; for(int j=0;j<20;j++)//查找有无该ID { if(strcmp(s,staff[j].id)==0) { flag = 1; break; } } if(i==6 && s[0]=='1' && flag) { printf("员工编号正确\n"); return 1; } else { printf("员工编号错误\n"); return 0; } }; //校验码检查函数 int Verification(char *p1,char *p2) { char s[7]; for(int i=0;i<6;i++) { s[i] = *p1; } //s数组反序 for(int i=1;i<6;i++) { s[i]=*(p1+6-i); } //新数组 for(int i=1;i<6;i++) { //ASCII码 数字'0'编号为48,减48或'0' s[i]+=*(p1+i)-'0'; } if(strcmp(s,p2)==0) return 1; else return 0; }; //根据输入的id匹配员工 SS *match(char number[7]) { for(int i=0;i<20;i++) { if(strcmp(number,staff[i].id)==0) { // printf("i:%d\n",i); // printf("输入的id:%s\n",number); // printf("匹配的id:%s\n",staff[i].id); // printf("匹配的地址:%p\n",&staff[i]); return &staff[i]; } } }; void clock_in(double time_cpy) //上班打卡 { int flag = 1; char number[7] = {0}; while(flag) { printf("请输入员工编号\n"); gets(number); if(judge_Verification(number)) { flag = 0; } } char check[7] = {0}; flag = 1; while(flag) { printf("请输入校验码\n"); gets(check); if(Verification(number,check)) { flag = 0,printf("上班打卡成功\n\n"); SS *staffx; staffx = match(number); gettimeofday(&(staffx->in_time), NULL); if(staffx->check5 == 1) { //弹性打卡 if(time_cpy<WORKSTARTTIME+2) staffx->check1 = 1; else if(time_cpy>WORKSTARTTIME+2 && time_cpy<WORKENDTIME) staffx->check2 = 1; staffx->check5 = 0; } else { if(time_cpy<WORKSTARTTIME) staffx->check1 = 1;//正常上班 else if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staffx->check2 = 1;//迟到 } } else printf("校验码错误\n\n"); } } void clock_out(double time_cpy)//下班打卡 { char number[7] = {0}; int flag = 1; while(flag) { printf("请输入员工编号\n"); gets(number); if(judge_Verification(number)) { flag = 0; } //else judge_Verification(); } SS *staffx; staffx = match(number); printf("下班打卡成功\n\n"); if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staffx->check3 = 1; else if(time_cpy>WORKENDTIME) staffx->check4 = 1; gettimeofday(&staffx->out_time, NULL); staffx->workhour_count += mytimer1(staffx->in_time,staffx->out_time); } void clockin_machine_start() //打卡机 { //开启打卡机 printf("输入1开启打卡机\n"); int flag = 1; while(flag) { char s = getchar(); char ss = getchar();//存入换行符 if(s == '1') { flag = 0; printf("打卡机已开启\n"); gettimeofday(&program_start_time, NULL); } else printf("指令错误,输入1开启打卡机\n"); } log_in(); //start_time1 = clock(); //程序总的运行时间 double time = PROGRAMSTARTTIME;//此处必须刷新一次即输入3,再打卡为正确时间 do{ //所有时间单位为h int time_cpy = (int)time % DAY_PER_HOUR;//打卡机当前时间 int time_cpy2 = time / DAY_PER_HOUR;//打卡机工作了几天 while(time_cpy<=WORKSTARTTIME) { //上班打卡 printf("上班时间\n"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); //记录每个人的上班打卡时间,并且令check1 = 1 //若该段时间没有打卡,check1 = 0 printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n"); char s = getchar(); char ss = getchar();//存入换行符 switch (s) { case '1':{ printf("上班打卡\t"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); clock_in(time_cpy); break; } case '2':{ printf("该时间无法下班打卡\n"); break; } default:{ printf("\n");break; } } break; } while(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) { printf("工作时间\n"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n"); char s = getchar(); char ss = getchar();//存入换行符 switch (s) { case '1':{ printf("上班打卡\t"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); clock_in(time_cpy); break; } case '2':{ printf("下班打卡\t"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); clock_out(time_cpy); break; } default:{ printf("\n");break; } } for(int i=0;i<3;i++)//只录入三个人用于测试 { //若check1 == 0,该时间段打卡,则为迟到 if(staff[i].check2 ==1) staff[i].late_date[staff[i].late_count] = time_cpy2,staff[i].late_count += 1; //若check1 == 0,该时间段未打卡,在下班时间后记录为缺勤 //若check1 == 1,该时间段打卡记为早退 if(staff[i].check1 == 1 && staff[i].check3 == 1) staff[i].leave_early_date[staff[i].leave_early_count] = time_cpy2,staff[i].leave_early_count += 1; } break; } while(time_cpy>=WORKENDTIME) { printf("下班时间\n"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); //记录缺勤 for(int i=0;i<3;i++)//3个人 { if(staff[i].check1 == 0 && staff[i].check2 ==0) staff[i].late_date[staff[i].late_count] = time_cpy2,staff[i].absence_count += 1; } //下班打卡时间 printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n"); char s = getchar(); char ss = getchar();//存入换行符 switch (s) { case '1':{ printf("当前无法上班打卡\t"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); break; } case '2':{ printf("下班打卡\t"); printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy); clock_out(time_cpy); break; } default:{ printf("\n");break; } } break; } //每经过一天的操作 while(time_cpy2>1) { //忘记下班打卡,记录为缺勤 for(int i=0;i<20;i++) { if((staff[i].check1 == 1 || staff[i].check2 == 1) && (staff[i].check3 == 0 || staff[i].check4 == 0)) { //staff[i].workhour_count += 0; staff[i].absence_count += 1; } //弹性打卡制,若前一天上班时长超过规定时长3小时以上,第二天迟到2小时以内不算迟到 if(mytimer1(staff[i].in_time,staff[i].out_time)-3>=(WORKSTARTTIME-WORKENDTIME)) { staff[i].check5 = 1; } //状态归零 staff[i].check1 = 0; staff[i].check2 = 0; staff[i].check3 = 0; staff[i].check4 = 0; } break; } gettimeofday(&program_end_time, NULL); time = mytimer1(program_start_time,program_end_time) + PROGRAMSTARTTIME; }while(time < DAY_PER_HOUR * WORKDAY); //打印员工的打卡信息 printf("*******************************\n" "考勤周报\n\n"); for(int i=0;i<3;i++) printWorkMsg(staff[i]); printf("*******************************\n\n"); //打印奖惩信息 printf("*******************************\n"); printRewardList(); printPunishList(); printf("*******************************\n"); } int main() { clockin_machine_start(); return 0; }