欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

打卡机核心功能实现

程序员文章站 2024-01-03 09:07:46
...

C语言小项目—上下班打卡机(核心功能实现)

 

项目简介:

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

 

任务过程:

 
  1、创建项目
  2、合理定义所需函数,主函数中只允许有 clockin_machine_start()调用
  3、按照任务概述实现函数流程
  4、调试修改

 

测试及部分代码:

 
一、上班时长设置
 

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "Global.h"

void ClockIn_machine_start();
void ClockIn();
void ClockOut();
int Check();
void ReHours();
void UpDateTime(int pattern);
void WeekChart(int day, int duringTime);



int number;  //员工编号
int pattern = 1;  //打卡模式(1为上班打卡,2为下班打卡)
int startTimes[5] = { 0 };        //上班打卡次数限制(每日1次)
int stopTimes[5] = { 0 };	      //下班打卡次数限制(每日3次,允许误打)
clock_t openTime, insert, start, stop;
long duration;   //打卡持续时长
int officeHours = 9;   //上班时间,默认为9小时
int day = 0;       //打卡日期
int hour;      //打卡当天时间(时)
int minute;    //打卡当天时间(分)
int duringTime;   //实际上班时间
int times_1 = 0;   //迟到次数
int times_2 = 0;   //早退次数
int times_3 = 0;   //缺卡次数
int chart[5] = { 0 };



int main(int argv, char *argc[]) {

	ClockIn_machine_start();
	system("PAUSE");
	return 0;

}

void ClockIn_machine_start()
{

	//规定上班时间
	ReHours();

	while (1)
	{
		//打卡模式选择
		printf("\n***************************************************************\n\n");
		printf("                   1.上班打卡\n");
		printf("                   2.下班打卡\n");
		printf("                   3.当前时间\n");
		printf("\n***************************************************************\n\n");

		printf("输入“3”可获取当前时间\n输入“1”或“2”进行打卡模式选择:\n");
		scanf_s("%d", &pattern);

		if (pattern == 1)
		{
			if (startTimes[day] == 0) {
				//上班打卡
				ClockIn();
			}
			else
			{
				printf("请勿在一天中重复上班打卡\n");
				UpDateTime(0);
			}
		}
		else if (pattern == 2)
		{
			if (stopTimes[day] < 3) {
				//下班打卡
				ClockOut();
			}
			else
			{
				printf("今日下班打卡次数已达上线\n");
				UpDateTime(0);
			}
		}
		else if (pattern == 3)
		{
			//显示当前时间
			UpDateTime(0);
		}
		else
		{
			printf("打卡失败,请输入正确的指令!!!\n");
		}

	}

}

void ReHours()
{
	printf("***************************************************************");
	printf("\n\n                    上班时长设置\n");
	printf("\n***************************************************************\n\n");

	char reFlag = 'n';
	printf("是否自定义上班时长(默认上班时长为 9 小时)  [Y/n]\n");
	reFlag = getchar();

	if (reFlag == 'Y' || reFlag == 'y')
	{
		printf("设置上班时长:\n");

		scanf_s("%d", &officeHours);
	}

	printf("打卡机开启\n");
	openTime = clock();     //设置好打卡时长后,打卡机开启

}

 
打卡机核心功能实现

 
二、上班打卡
 

void ClockIn()
{
	printf("\n***************************************************************");
	printf("\n\n                   上班打卡");
	printf("\n");
	printf("\n***************************************************************\n\n");


	int checkFlag = 0;
	//效验编号
	checkFlag = Check();
	if (checkFlag)
	{

		int checkNumber;
		int tempNumber;
		int times = 0;
		checkNumber = number + number % 10 * 10000 + (number % 100 - number % 10) * 100
			+ (number % 1000 - number % 100) + number % 10000 / 1000 * 10 + number % 100000 / 10000;
		printf("效验码:%d\n", checkNumber);
		printf("请输入上述效验码:\n");

		scanf_s("%d", &tempNumber);
		if (tempNumber == checkNumber)
		{
			printf("上班打卡成功!!!\n");
			startTimes[day] += 1;   //当日上班打卡次数加 1
			UpDateTime(pattern);
			times = 0;
			return;
		}
		else
		{
			do {
				times++;
				printf("效验码错误,请重新输入效验码:%d\n", checkNumber);
				scanf_s("%d", &tempNumber);
				if (tempNumber == checkNumber)
				{
					printf("上班打卡成功!!!\n");
					startTimes[day] += 1;
					UpDateTime(pattern);
					times = 0;
					return;
				}
			} while (times < 3);
			if (times == 3)
			{
				printf("错误次数过多,请重新打卡\n");
				times = 0;
				return;
			}
		}

		checkFlag = 0;
	}

	return;

}

 
打卡机核心功能实现
 
每日仅支持一次上班打卡

 
打卡机核心功能实现
 
上班打卡迟到记录
 
打卡机核心功能实现
 

三、下班打卡
 

void ClockOut()
{
	printf("\n***************************************************************");
	printf("\n\n                   2.下班打卡");
	printf("\n");
	printf("\n***************************************************************\n\n");

	int tempNumber;
	printf("请输入您的编号:\n");

	scanf_s("%d", &tempNumber);

	while (1)
	{
		if (number == tempNumber)
		{
			printf("下班打卡成功!!!\n");
			UpDateTime(pattern);
			stopTimes[day] += 1;   //当日下班打卡次数加 1
			break;
		}
		else
		{
			printf("请先进行上班打卡\n");
			break;
		}

	}
}

 
下班打卡早退记录
 
打卡机核心功能实现
 
每日允许三次下班误打卡

 打卡机核心功能实现
 
四、弹性打卡
 
计时部分代码
 

void UpDateTime(int pattern_1)
{
	insert = clock();
	duration = (insert - openTime) / CLOCKS_PER_SEC;   //将时间转换为秒

	hour = (7 + duration / 6) % 24;
	minute = (int)(duration / 6.0 * 60) % 60;

	printf("当前时间: ");
	if (duration / 6 < 17)
	{
		day = 0;
	}
	else
	{
		day = 1 + (duration / 6 - 17) / 24;
	}

	switch (day % 5)
	{
	case 0:
		printf("星期一");
		break;
	case 1:
		printf("星期二");
		break;
	case 2:
		printf("星期三");
		break;
	case 3:
		printf("星期四");
		break;
	case 4:
		printf("星期五");
		break;
	}


	printf("  %d : %d\n", hour, minute);


	if (pattern_1 == 1)
	{
		start = clock();
		if (hour > 9)
		{
			printf("上班打卡迟到\n");
			times_1++;

			if (hour - 9 <= 2 && day != 0)
			{
				if (chart[day - 1] > (3 + officeHours) * 60)
				{
					times_1--;
					printf("但由于昨日超时长工作,今日上班迟到撤销\n");
				}
			}
		}




	}
	else if (pattern_1 == 2)
	{
		stop = clock();
		duringTime = (stop - start) / CLOCKS_PER_SEC;   //将时间转换为秒




		if (duringTime / 6 * 60 + minute < officeHours * 60)
		{
			printf("今日上班时长:  %d小时%d分钟\n", duringTime / 6, minute);
			printf("早退  %d分钟\n", officeHours * 60 - duringTime / 6 * 60 - minute);
			times_2++;


		}

		if (stopTimes[day] > 0)
		{
			times_2--;   //允许误打卡,一天中多次打卡则减去累加的早退次数
		}

		WeekChart(day, duringTime);

	}




}

 打卡机核心功能实现
 
五、周日报测试(周五下班后自动生成周日报,显示周平均上班时长,周迟到、早退、缺卡次数)
 

void WeekChart(int day, int duringTime_1)
{
	chart[day] = (int)(duringTime_1 / 6.0 * 60);
	if (day == 4)
	{
		printf("本周打卡结束,生成周报表\n\n");

		for (int i = 0; i < 5; i++)
		{
			switch (i)
			{
			case 0:
				printf("星期一					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 1:
				printf("星期二					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);

				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 2:
				printf("星期三					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 3:
				printf("星期四					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 4:
				printf("星期五					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;

			}
		}

		int sum = 0;

		for (int j = 0; j < 5; j++)
		{
			sum += chart[j];
		}


		printf("周平均上班时长: %d分钟\n", sum / 5);
		printf("迟到次数: %d\n", times_1);
		printf("早退次数: %d\n", times_2);
		printf("缺卡次数: %d\n", times_3);


	}
}

 
打卡机核心功能实现
 
 
 

完整代码(欢迎各位在评论区交流)

 

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include "Global.h"

void ClockIn_machine_start();
void ClockIn();
void ClockOut();
int Check();
void ReHours();
void UpDateTime(int pattern);
void WeekChart(int day, int duringTime);


int number;  //员工编号
int pattern = 1;  //打卡模式(1为上班打卡,2为下班打卡)
int startTimes[5] = { 0 };        //上班打卡次数限制(每日1次)
int stopTimes[5] = { 0 };	      //下班打卡次数限制(每日3次,允许误打)
clock_t openTime, insert, start, stop;
long duration;   //打卡持续时长
int officeHours = 9;   //上班时间,默认为9小时
int day = 0;       //打卡日期
int hour;      //打卡当天时间(时)
int minute;    //打卡当天时间(分)
int duringTime;   //实际上班时间
int times_1 = 0;   //迟到次数
int times_2 = 0;   //早退次数
int times_3 = 0;   //缺卡次数
int chart[5] = { 0 };

int main(int argv, char *argc[]) {

	ClockIn_machine_start();
	system("PAUSE");
	return 0;

}

void ClockIn_machine_start()
{

	//规定上班时间
	ReHours();

	while (1)
	{
		//打卡模式选择
		printf("\n***************************************************************\n\n");
		printf("                   1.上班打卡\n");
		printf("                   2.下班打卡\n");
		printf("                   3.当前时间\n");
		printf("\n***************************************************************\n\n");

		printf("输入“3”可获取当前时间\n输入“1”或“2”进行打卡模式选择:\n");
		scanf_s("%d", &pattern);

		if (pattern == 1)
		{
			if (startTimes[day] == 0) {
				//上班打卡
				ClockIn();
			}
			else
			{
				printf("请勿在一天中重复上班打卡\n");
				UpDateTime(0);
			}
		}
		else if (pattern == 2)
		{
			if (stopTimes[day] < 3) {
				//下班打卡
				ClockOut();
			}
			else
			{
				printf("今日下班打卡次数已达上线\n");
				UpDateTime(0);
			}
		}
		else if (pattern == 3)
		{
			//显示当前时间
			UpDateTime(0);
		}
		else
		{
			printf("打卡失败,请输入正确的指令!!!\n");
		}

	}


}


void ReHours()
{
	printf("***************************************************************");
	printf("\n\n                    上班时长设置\n");
	printf("\n***************************************************************\n\n");

	char reFlag = 'n';
	printf("是否自定义上班时长(默认上班时长为 9 小时)  [Y/n]\n");
	reFlag = getchar();

	if (reFlag == 'Y' || reFlag == 'y')
	{
		printf("设置上班时长:\n");

		scanf_s("%d", &officeHours);
	}

	printf("打卡机开启\n");
	openTime = clock();     //设置好打卡时长后,打卡机开启

}


void ClockIn()
{
	printf("\n***************************************************************");
	printf("\n\n                   上班打卡");
	printf("\n");
	printf("\n***************************************************************\n\n");


	int checkFlag = 0;
	//效验编号
	checkFlag = Check();
	if (checkFlag)
	{

		int checkNumber;
		int tempNumber;
		int times = 0;
		checkNumber = number + number % 10 * 10000 + (number % 100 - number % 10) * 100
			+ (number % 1000 - number % 100) + number % 10000 / 1000 * 10 + number % 100000 / 10000;
		printf("效验码:%d\n", checkNumber);
		printf("请输入上述效验码:\n");

		scanf_s("%d", &tempNumber);
		if (tempNumber == checkNumber)
		{
			printf("上班打卡成功!!!\n");
			startTimes[day] += 1;   //当日上班打卡次数加 1
			UpDateTime(pattern);
			times = 0;
			return;
		}
		else
		{
			do {
				times++;
				printf("效验码错误,请重新输入效验码:%d\n", checkNumber);
				scanf_s("%d", &tempNumber);
				if (tempNumber == checkNumber)
				{
					printf("上班打卡成功!!!\n");
					startTimes[day] += 1;
					UpDateTime(pattern);
					times = 0;
					return;
				}
			} while (times < 3);
			if (times == 3)
			{
				printf("错误次数过多,请重新打卡\n");
				times = 0;
				return;
			}
		}

		checkFlag = 0;
	}

	return;

}


int Check()
{
	//首先录入员工编号
	printf("请输入您的编号:\n");


	scanf_s("%d", &number);
	int i = 0;

	//判断员工编号输入是否正确
	while (number / 100000 != 1)
	{
		i++;
		printf("编号输入有误,请重新输入\n");
		scanf_s("%d", &number);
		if (number / 100000 == 1)
		{
			i = 0;
			return 1;
		}
		else if (i > 2)
		{
			printf("编号输入错误次数过多,打卡失败\n");
			i = 0;
			return 0;
		}
	}
	return 1;

}


void ClockOut()
{
	printf("\n***************************************************************");
	printf("\n\n                   2.下班打卡");
	printf("\n");
	printf("\n***************************************************************\n\n");

	int tempNumber;
	printf("请输入您的编号:\n");

	scanf_s("%d", &tempNumber);

	while (1)
	{
		if (number == tempNumber)
		{
			printf("下班打卡成功!!!\n");
			UpDateTime(pattern);
			stopTimes[day] += 1;   //当日下班打卡次数加 1
			break;
		}
		else
		{
			printf("请先进行上班打卡\n");
			break;
		}

	}
}


void UpDateTime(int pattern_1)
{
	insert = clock();
	duration = (insert - openTime) / CLOCKS_PER_SEC;   //将时间转换为秒

	hour = (7 + duration / 6) % 24;
	minute = (int)(duration / 6.0 * 60) % 60;

	printf("当前时间: ");
	if (duration / 6 < 17)
	{
		day = 0;
	}
	else
	{
		day = 1 + (duration / 6 - 17) / 24;
	}

	switch (day % 5)
	{
	case 0:
		printf("星期一");
		break;
	case 1:
		printf("星期二");
		break;
	case 2:
		printf("星期三");
		break;
	case 3:
		printf("星期四");
		break;
	case 4:
		printf("星期五");
		break;
	}


	printf("  %d : %d\n", hour, minute);


	if (pattern_1 == 1)
	{
		start = clock();
		if (hour > 9)
		{
			printf("上班打卡迟到\n");
			times_1++;

			if (hour - 9 <= 2 && day != 0)
			{
				if (chart[day - 1] > (3 + officeHours) * 60)
				{
					times_1--;
					printf("但由于昨日超时长工作,今日上班迟到撤销\n");
				}
			}
		}




	}
	else if (pattern_1 == 2)
	{
		stop = clock();
		duringTime = (stop - start) / CLOCKS_PER_SEC;   //将时间转换为秒




		if (duringTime / 6 * 60 + minute < officeHours * 60)
		{
			printf("今日上班时长:  %d小时%d分钟\n", duringTime / 6, minute);
			printf("早退  %d分钟\n", officeHours * 60 - duringTime / 6 * 60 - minute);
			times_2++;


		}

		if (stopTimes[day] > 0)
		{
			times_2--;   //允许误打卡,一天中多次打卡则减去累加的早退次数
		}

		WeekChart(day, duringTime);

	}




}

void WeekChart(int day, int duringTime_1)
{
	chart[day] = (int)(duringTime_1 / 6.0 * 60);
	if (day == 4)
	{
		printf("本周打卡结束,生成周报表\n\n");

		for (int i = 0; i < 5; i++)
		{
			switch (i)
			{
			case 0:
				printf("星期一					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 1:
				printf("星期二					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);

				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 2:
				printf("星期三					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 3:
				printf("星期四					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;
			case 4:
				printf("星期五					");
				if (chart[i])
				{
					printf("打卡时长:%d分钟\n", chart[i]);
				}
				else
				{
					printf("缺卡\n");
					times_3++;
				}
				break;

			}
		}

		int sum = 0;

		for (int j = 0; j < 5; j++)
		{
			sum += chart[j];
		}


		printf("周平均上班时长: %d分钟\n", sum / 5);
		printf("迟到次数: %d\n", times_1);
		printf("早退次数: %d\n", times_2);
		printf("缺卡次数: %d\n", times_3);


	}
}

上一篇:

下一篇: