打卡机的设计——基本功能

本文介绍了一款C++实现的打卡机设计,包括基本功能和功能完善。打卡机具备计时、打卡、签退功能,能记录工作时长、处理早退、缺席情况,并实施弹性打卡制。设计中使用非阻塞IO处理用户输入,用结构体和宏定义处理时间转换,以及通过开关语句实现功能列表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打卡机设计

任务概述

应市场需求,某工程师现设计了一款新上下班打卡机,打卡机具有以下功能:
(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)
 {<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值