打卡机核心功能实现(C语言)

news/2024/10/28 0:28:37/

打卡机核心功能实现(C语言)

任务分析

应市场需求,某工程师现设计了一款新上下班打卡机,打卡机具有以下功能:
(1)上班打卡,员工具有编号(首位为 1 的六位编号),输入编号后,再输入校验码,校验码生成规则:员工编号除首位反序,再与员工编号求和,如:员工编号,110086,校验码为 178087。校验码错误即打卡失败。记录打卡时间 。
(2)下班打卡,只需输入员工编号即可。记录打卡时间,显示该人员今天上班时长,如果上班时长不够,显示早退 xx 分钟。可以更新下班打卡时间。无下班打卡显示缺卡。
(3)可以设置规定上班时长,如 9 小时
(4)测试需要可以规定 6 秒=实际 1 小时,每次测试,输入指令后,开启打卡机,打卡机开启模拟时间为:周一早上七点。程序运行结束为周五晚 12 点。
(5)实行弹性打卡制,如前一天上班时长超过规定时长 3 小时以上,第二天迟到 2 小时以内不算迟到。
(6)打卡机运行结束之前,每周该打卡机会生成每周考勤周报,显示周平均上班时长,周迟到,早退,缺卡次数等。
要求:合理定义所需函数,主函数中只允许有 clockin_machine_start() 调用。

任务要求是主函数中只允许有clockin_machine_start()的调用,因此在主函数中仅进行该函数的调用,具体实现放在主函数外部。

int main()
{clockin_machine_start();return 0;
}

将任务划分为三个主要的模块,分别是员工上班打卡、下班打卡、时间统计与处理。

首先是员工上班打卡的实现,打卡所需的工作封装在ClockIn()函数中,该函数传入的参数含义分别为编号、验证码和编号长度,其中InitInfor()函数用于实现员工编号和验证码的录入,其中包括信息格式的判断,并通过CheckInfor(id, captcha, size)函数来判断录入的信息内容是否通过校验。

void ClockIn(char id[SIZE], char captcha[SIZE], int size)
{while(1){printf("Please input the id:>"); InitInfor(id, size);printf("Please input the code:>"); InitInfor(captcha, size);if(CheckInfor(id, captcha, size) == 0){printf("Ok! You've clocked in.'\n");break;}else if(CheckInfor(id, captcha, size) != 0){printf("Sorry, please input the right infor.\n");} }
}

第二部分是员工下班打卡,因为下班只需要输入员工编号,所以此时传入参数为员工编号和编号长度,将下班打卡时录入的信息与员工编号进行匹配,如果匹配成功,则打卡成功。

void ClockOut(char id[SIZE], int size)
{char id_buf[SIZE] = {'0'};while(1){printf("Please input the id:>");InitInfor(id_buf, size);if(memcmp(id_buf, id, size) == 0){printf("Ok! You've clocked out.\n");break;}else if(memcmp(id_buf, id, size) != 0){printf("Sorry, please input the right infor.\n");}} 	
}

第三部分为时间管理,通过time()函数来记录当前程序语句运行时的时间,通过对多个程序点的时间计算,完成员工上班工作时长、迟到、早退等信息的统计。

time_t clockin_time;
time(&clockin_time);

因为打卡机在周内要一直执行,此时就需要在每个阶段进行时间的获取及处理,但是在打卡机功能中,有这样一个需求,员工在每天工作结束后如果无下班打卡则记为缺卡,但是如果要实现该功能,则程序获取输入与程序统计时间就会产生矛盾,员工一直没有输入,则程序处于获取输入的阻塞状态中,那么时间就无法计算。
在Linux系统下可以通过以下方法解决此问题:(使用非阻塞IO)

#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>int flag1, flag2;
if(flag1 = fcntl(STDIN_FILENO, F_GETFL, 0) < 0)
{perror("fcntl");return -1;
}
flag2 = flag1 | O_NONBLOCK;
fcntl(STDIN_FILENO, F_SETFL, flag2);  //非阻塞// 执行动作fcntl(STDIN_FILENO, F_SETFL, flag1);  //阻塞

代码实现

clockin_machine.h

#ifndef __CLOCKIN_MACHINE_H__
#define __CLOCKIN_MACHINE_H__#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>#define SIZE 6  // bits of id 
#define WEEKDAY 5  // weekday 
#define ONEDAY 86400  // ONEDAY is 86400s long 
#define TWOHOUR 7200  // TWOHOUR is 86400s long 
#define THREEHOUR 10800  // THREEHOUR is 86400s long 
#define ALL 0  // ALL is the first line of the time table, means working time
#define IN 1  // ALL is the second line of the time table, means clock_in time
#define OUT 2  // ALL is the third line of the time table, means clock_out timetime_t start_time;  // the machine start at 7 am Mon.
int open_time;  // clock_in time = 9 am
int close_time;  // clock_out time = 5 pm
int work_time[3][WEEKDAY];  // time table 
int arrive_late;
int leave_early;void clockin_machine_start();
void BannerIn(int day);
void ClockIn(char id[SIZE], char captcha[SIZE], int size);
void InitInfor(char buf[SIZE], int size);
int CheckInfor(char id[SIZE], char captcha[SIZE], int size);
void BannerOut(); 
void ClockOut(char id[SIZE], int size); 
void BannerFin(int day);
time_t reTime(time_t time);
void CountTime(time_t clockin_time, time_t clockout_time, int day);
void IsArriveLate(int day);
void IsLeaveEarly(int day);
int AverageTime(int weekday);
void DisplayCount(int ave_time, int arrive_late, int leave_early);#endif //__CLOCKIN_MACHINE_H__

main.c

#include "clockin_machine.h"int main()
{clockin_machine_start();return 0;
}

clockin_machine.c

#include "clockin_machine.h"void clockin_machine_start()
{time(&start_time);start_time = reTime(start_time);open_time = start_time + TWOHOUR; close_time = start_time + (10 * TWOHOUR);arrive_late = 0;leave_early = 0;int day = 0;do{char id[SIZE] = {'0'};  // the id of the employee char captcha[SIZE] = {'0'};  // identificationBannerIn(day);ClockIn(id, captcha, SIZE);  // clock intime_t clockin_time;time(&clockin_time);  // write down the time of clocking inclockin_time = reTime(clockin_time);  // change the form of the timeBannerOut();ClockOut(id, SIZE);  // clock out time_t clockout_time;time(&clockout_time);  // write down the time of clocking outclockout_time = reTime(clockout_time);  // change the form of the timeCountTime(clockin_time, clockout_time, day);  // count the worker's information all day  IsArriveLate(day);  // did the worker arrive late IsLeaveEarly(day);  // did the worker leave earlyBannerFin(day);day++; }while(day < WEEKDAY);int ave_time = AverageTime(WEEKDAY);DisplayCount(ave_time, arrive_late, leave_early);}void BannerIn(int day)
{switch(day+1){case 1:printf("Mon.\n");break;case 2:printf("Tue.\n");break;case 3:printf("Wed.\n");break;case 4:printf("Thur.\n");break;case 5:printf("Fri.\n");break;default:break;}printf("****************************************\n"); printf("------------please clock in-------------\n"); 
}void ClockIn(char id[SIZE], char captcha[SIZE], int size)
{while(1){printf("Please input the id:>"); InitInfor(id, size);printf("Please input the code:>"); InitInfor(captcha, size);if(CheckInfor(id, captcha, size) == 0){printf("Ok! You've clocked in.'\n");break;}else if(CheckInfor(id, captcha, size) != 0){printf("Sorry, please input the right infor.\n");} }}void InitInfor(char buf[SIZE], int size)
{int index = 0;char tmp;while((tmp=getchar()) != '\n'){buf[index] = tmp;index++;}if(index!=size || buf[0]!='1'){printf("Sorry, please input the right infor:>");InitInfor(buf, size);}
}int CheckInfor(char id[SIZE], char captcha[SIZE], int size)
{// if the code is right, retunr 0int i = 0;char tmp[size];strncpy(tmp, id, size);// Except for the first number of employees, sum up in reverse order for(i=1; i<size; i++){tmp[i] = (char)(((int)tmp[i])%48 + (int)id[size-i]); }return strcmp(tmp, captcha);	
} void BannerOut()
{printf("------------please clock out------------\n"); 
}void ClockOut(char id[SIZE], int size)
{char id_buf[SIZE] = {'0'};while(1){printf("Please input the id:>");InitInfor(id_buf, size);if(memcmp(id_buf, id, size) == 0){printf("Ok! You've clocked out.\n");break;}else if(memcmp(id_buf, id, size) != 0){printf("Sorry, please input the right infor.\n");}} 	
}void BannerFin(int day)
{int hour = work_time[ALL][day] / 3600;int min = (work_time[ALL][day] - hour * 3600) / 60;printf("***************You worked%3dhour%3dmin**\n\n\n", hour, min);
}time_t reTime(time_t time)
{return time%ONEDAY;
}void CountTime(time_t clockin_time, time_t clockout_time, int day)
{work_time[ALL][day] = (clockout_time - clockin_time) * 10 * 60;work_time[IN][day] = clockin_time;work_time[OUT][day] = clockout_time;
}void IsArriveLate(int day)
{if(day > 0){if(work_time[OUT][day-1]-close_time >= THREEHOUR)//work hard last day {if(work_time[IN][day]-open_time <= TWOHOUR){}else if(work_time[IN][day]-open_time > TWOHOUR)// over two hours{arrive_late++;}}else if(work_time[OUT][day-1]-close_time < THREEHOUR)// did not work hard {if(work_time[IN][day] <= open_time){}else if(work_time[IN][day] > open_time)//arrive late{arrive_late++;}}}else if(day == 0) // if today is Mon.{if(work_time[IN][day] <= open_time){}else if(work_time[IN][day] > open_time)//arrive late{arrive_late++;}}
} void IsLeaveEarly(int day)
{if(work_time[OUT][day] >= close_time){}else if(work_time[OUT][day] < close_time){leave_early++;}
}int AverageTime(int weekday)
{int i = 0;int sum = 0;for(i=0; i<weekday; i++){sum = sum + work_time[ALL][i];}return sum/weekday;
}void DisplayCount(int ave_time, int arrive_late, int leave_early)
{int hour = ave_time / 3600;int min = (ave_time - hour * 3600) / 60;printf("vvvvvvvvvvvvv SUM vvvvvvvvvvvv\n");printf("··average time> %2dh%2dm\n", hour, min);printf("··arrive late > %dtimes\n", arrive_late);printf("··leave early > %dtimes\n", leave_early);
}

http://www.ppmy.cn/news/144384.html

相关文章

用树莓派制作刷脸打卡机——硬件部分

软件部分&#xff1a;https://blog.csdn.net/d_l_w_d_l_w/article/details/112273581 一.上手树莓派 1.安装系统 1.1 下载链接&#xff1a; ​ https://www.raspberrypi.org/software/operating-systems/#raspberry-pi-os-32-bit 1.2写入镜像 使用 Win32DiskImager 写入 …

用 node-xlsx 将从打卡机中导出的考勤信息处理生成考勤表

导出来的考勤信息表&#xff08;只是获取打卡信息并处理成报表.xlsx , 初始的表格没了&#xff09; 下图是 “报表.xlsx ” 看起来乱糟糟的&#xff0c;虽然能看但是需要花费大量的精力去处理才能成标准表格&#xff0c;下面我直接上代码&#xff08;代码里已有注释&#xff09…

视频打卡机是否可以应用了?

从GOOGLE近来公布的视频来看&#xff0c;视频识别还是蛮高的。举个例子&#xff0c;如果用在公司打卡上&#xff0c;就非常方便&#xff0c;只要从门口走进来&#xff0c;视频摄像头对准录一下&#xff0c;就可以实现打卡了&#xff0c;无接触&#xff0c;无停留。 如下图这样…

OpenHarmony成长计划#校园极客秀#碰一碰智能NFC打卡机

作品创意 NFC——近距离无线通讯技术目前已成为我们生活中随处可见、随手可用的技术&#xff0c;它可以提供轻松、安全、迅速的通信无线连接&#xff0c;被广泛地应用于各种场合&#xff0c;如公交一卡通、学生校园卡等。现在越来越多的智能手机都有NFC的功能&#xff0c;在这…

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

打卡机设计 任务概述 应市场需求&#xff0c;某工程师现设计了一款新上下班打卡机&#xff0c;打卡机具有以下功能&#xff1a; &#xff08;1&#xff09; 上班打卡&#xff0c;员工具有编号&#xff08;首位为 1 的六位编号&#xff09;&#xff0c;输入编号后&#xff0c;再…

打卡机

1.题目&#xff1a; Problem Description LPRJ小工厂是刚兴起不久的标准工厂&#xff0c;每天早上八点开始上班&#xff0c;每天工作八小时&#xff0c;但是由于LPRJ小工厂近来员工懈怠于工作&#xff0c;经常迟到&#xff0c;于是经理LP决定用考勤打卡机来记录员工的上班时间&…

共建、共享开源 EDA 共性技术框架 | 2023 开放原子全球开源峰会开源 EDA 分论坛即将启幕

电子电路设计自动化&#xff08;EDA&#xff09;融合了计算机、微电子、计算数学、图形学和人工智能等众多前沿技术&#xff0c;为集成电路设计、制造和封装等整个产业提供至关重要的自动化辅助设计能力。集成电路是支撑国民经济、社会发展和保障国家安全的基础性、先导性和战略…

打卡机核心功能实现

C语言小项目—上下班打卡机&#xff08;核心功能实现&#xff09; 项目简介&#xff1a; 应市场需求&#xff0c;某工程师现设计了一款新上下班打卡机&#xff0c;打卡机具有以下功能&#xff1a;   &#xff08;1&#xff09; 上班打卡&#xff0c;员工具有编号&#xff08;…