打卡机核心功能实现

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);


	}
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页