打卡机设计
任务概述
应市场需求,某工程师现设计了一款新上下班打卡机,打卡机具有以下功能:
(1) 上班打卡,员工具有编号(首位为 1 的六位编号),输入编号后,再
输入校验码,校验码生成规则:员工编号除首位反序,再与员工编号
求和,如:员工编号,110086,校验码为 178087。校验码错误即打
卡失败。记录打卡时间
(2) 下班打卡,只需输入员工编号即可。记录打卡时间,显示该人员今天
上班时长,如果上班时长不够,显示早退 xx 分钟。可以更新下班打
卡时间。无下班打卡显示缺卡。
(3) 可以设置规定上班时长,如 9 小时
(4) 测试需要可以规定 6 秒=实际 1 小时,每次测试,输入指令后,开启
打卡机,打卡机开启模拟时间为:周一早上七点。程序运行结束为周
五晚 12 点。
(5) 实行弹性打卡制,如前一天上班时长超过规定时长 3 小时以上,第
二天迟到 2 小时以内不算迟到。
(6) 打卡机运行结束之前,每周该打卡机会生成每周考勤周报,显示周平
均上班时长,周迟到,早退,缺卡次数等。
设计过程
本次设计分两个步骤:
步骤一:完成打卡机的基本功能,比如:计时及打卡。
步骤二:完善打卡机的功能,比如:弹性打卡。
1.打卡机的基本功能
1.1-打卡机计时功能与功能列表的实现
因测试需要规定6s为1h,则打卡机的1s为10m、1ms为600ms;
有因为在计时的同时需要响应用户的操作(打卡…)所以需要开启输入函数的非阻塞模式
1.1.1-非阻塞的IO的使用
在记时的同时需要响应用户的打卡等功能,有因为scanf函数默认是阻塞的所以我们需要开启非阻塞io。
代码如下:
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> int main(int argc, char const *argv[]) { int flags, flags2,test; //使用非阻塞io if(flags = fcntl(STDIN_FILENO, F_GETFL, 0) < 0) { perror("fcntl"); return -1; } flags |= O_NONBLOCK; if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { perror("fcntl"); return -1; } scanf("%d",&test); printf("#############1\n"); usleep(2000000); printf("***************2\n"); //关闭非阻塞io flags &= ~O_NONBLOCK; if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0) { perror("fcntl"); return -1; } scanf("%d",&test); return 0; }
1.1.2-打卡机记时功能实现与功能列表
要实现打卡机的时间记录功首先必须对打卡机的时候和现实时间进行对应最先想到的就是枚举
//实现代码 typedef unsigned long ulong; enum { milliseconds = 600; second = (milliseconds * 1000); minutes = (second * 60); hours = (minutes * 60); }
但是enum的成员变量都是int类型到hour的时候已经超出了int类型的表示范围。
所以换成结构体实现
//实现代码 typedef unsigned long ulong; struct MachineTime { ulong milliseconds; ulong seconds; ulong minutes; ulong hours; }TimeState; void machineTimer() { //打卡机时间对应 TimeState.milliseconds = 600; TimeState.seconds = (TimeState.milliseconds * 1000); TimeState.minutes = (TimeState.seconds * 60); TimeState.hours = (TimeState.minutes * 60); }
但使用这种方式又会导致每个时间都需要转换再计算,所以我们可以使用宏定义一个毫秒数在超出1000ms的时候对其进行转会成秒然后依次转化。
又因为需要存储5天(周一至周五)的数据所以可以将其存储在一个5行3列的数组当中。
在记时的同时我们可以用switch对输入的数据进行判断,实现功能列表功能。
用switch的好处在于可以美化代码,如使用if实现代码比较冗余;且用switch方便添加功能方便后期维护。
#include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include "../head/utils.h" typedef unsigned char uint8_t; typedef unsigned long uint64_t; #define millionsecond 600 int clockin_machine_start() { uint8_t timeRecorder[5][3] = { 0}; uint8_t currentDays = 0; char funcSelect; int flags; uint64_t msTmpRecord = 0; //周一早上七点打卡机开始工作 timeRecorder[0][2] = 7; //开启非阻塞io if(flags = fcntl(STDIN_FILENO, F_GETFL, 0) < 0) { perror("fcntl"); return -1; } flags |= O_NONBLOCK; if(fcntl(STDIN_FILENO, F_SETFL, flags) < 0) {<