打卡机任务

get到的新东西:
1、时间函数一定要同时定义在一个作用域下,否则会出现紊乱;
2、结构体数组的定义、初始化与函数调用(数组的函数调用)。

代码详情

#include <stdio.h>
#include <time.h>

/** 模拟:每小时长度,工作规定时长 */
#define HOUR 6
#define POWER 7
#define WORKTIME 54
#define WEEKDAY 5
#define STUFF 2
#define CD 6

/** 每天开、关机时间*/
time_t TimeOn,TimeOff;

/** 员工考勤表 */
struct Info
{
    char code[CD];
    int Schedule[2]; //每日上下班时间
    int L; //迟到
    int E; //早退
    int X; //旷工
    int F; //全勤
    int D[5]; // 每周持续上班时间
    int AVED;
};

/** 开机,打卡,退卡等子函数声明 */
void clockin_machine_start();
int CardOn(struct Info *ct, time_t tempClock);
int CardOff(struct Info *ct, time_t tempClock);

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

void clockin_machine_start()
{
    /** 一、初始化模式*/
    /** 1.1 员工信息录入与显示 */
    printf("---事先录入员工信息---\n");
    struct Info ct[STUFF]={};
    for(int i=0; i<STUFF; i++){
        printf("请输入%d/3员工的工号:", i+1);
        gets(ct[i].code);
    }
    for(int i=0; i<STUFF; i++){
        printf("%d/3员工的工号: %s\n", i+1, ct[i].code);
    }
    /** 1.2  时间更新 */
    int day = 1;

    /** 二、 工作模式 */
    while(day<=WEEKDAY){
        /** 1 报时 */
        printf("---星期 %d---\n", day);

        /** 2 模拟一天工作*/
        /** 2.1 初始化各时间节点、员工起始表 */
        time(&TimeOn);
        printf("!!!实际时间为: %s\n", ctime(&TimeOn));
        for(int i=0; i<STUFF; i++){
            ct[i].Schedule[0]=0;
            ct[i].Schedule[1]=0;
        }

        /** 2.2 初始化操作符、通常结束符、提前结束符 */
        int opt;
        int flag_uni = 1;
        int flag_cnt = 0;

        /** 2.3 功能循环放送(整天内可以随时打/退卡) */
        while(flag_uni){
            printf("--*--1.打卡--*--2.退卡--*--\n>>");
            scanf("%d", &opt);
            getchar();

            /** 2.3.1 打卡操作 */
            if(opt==1){
                /** 2.3.1.1 避免子函数内定义造成计时紊乱 */
                time_t tempClock;
                /** 2.3.1.2 打卡操作子程序 */
                int tempId = CardOn(ct, tempClock);
                /** 2.3.1.3 打卡反馈信息 */
                if(tempId != -1){
                    /** 显示信息 */
                    printf("$ %s 号员工上班时间为 ", ct[tempId].code);
                    int Gap = ct[tempId].Schedule[0]-TimeOn;
                    printf(" %d : %2d", Gap/HOUR + POWER, Gap%HOUR*10);
                    /** 记录信息:弹性迟到法则 */
                    if(ct[tempId].Schedule[0]-TimeOn <= 2*HOUR){
                        printf(",今日按时到岗。\n");
                    }else if(day>1 && ct[tempId].D[day-2]>=10*HOUR && ct[tempId].Schedule[0]-TimeOn<=4*HOUR){
                        printf(",昨日加班,不算迟到。\n");
                    }else{
                        printf(",上班迟到,予以警告!\n");
                        ct[tempId].L++;
                    }
                }

            /** 2.3.2 退卡操作 */
            }else if(opt==2){
                /** 2.3.2.1 避免子函数内定义造成计时紊乱 */
                time_t tempClock;
                /** 2.3.2.2 退卡操作子程序 */
                int tempId = CardOff(ct, tempClock);
                /** 2.3.2.3 退卡反馈信息 */
                if(tempId != -1){
                    /** 所有人都下班时,自动关机 */
                    flag_cnt++;
                    if(flag_cnt == STUFF) flag_uni = 0;
                    /** 显示信息 */
                    printf("$ %s 号员工下班时间为 ", ct[tempId].code);
                    int Gap = ct[tempId].Schedule[1]-TimeOn;
                    printf(" %d : %2d", Gap/HOUR + POWER, Gap%HOUR*10);
                    /** 记录信息:工作时长,早退 */
                    int tempDuration = ct[tempId].Schedule[1]-ct[tempId].Schedule[0];
                    ct[tempId].D[day-1] = tempDuration;
                    if(tempDuration < 8*HOUR){
                        ct[tempId].E++;
                        printf(",早退 %d 分钟,予以警告!\n", (8*HOUR-tempDuration)*10);
                    }else{
                        printf(",多工作 %d 分钟,", (tempDuration-8*HOUR)*10);
                        /** 全勤判断:既不迟到也不早退 */
                        if(ct[tempId].Schedule[0]-TimeOn <= 2*HOUR){
                            ct[tempId].F++;
                            printf("全勤鼓励!\n");
                        }else if(day>1 && ct[tempId].D[day-2]>=10*HOUR && ct[tempId].Schedule[0]-TimeOn<=4*HOUR){
                            ct[tempId].F++;
                            printf("全勤鼓励!\n");
                        }
                    }
                }
            }
            /** 2.3.3 重置操作符 */
            opt = 0;

            /** 2.3.4 是否到达截止时间并关机 */
            time(&TimeOff);
            if(TimeOff >= TimeOn + 17*HOUR){
                printf("%s\n", ctime(&TimeOff));
                printf("PowerOff!\n");
                flag_uni = 0;
                /** 2.3.3.1 每日结算,是否有旷工*/
                for(int i=0; i<STUFF; i++){
                    if(ct[i].Schedule[1]==0 || ct[i].Schedule[1]==0){
                        ct[i].X++;
                        printf("%s 号员工今日旷工\n", ct[i].code);
                    }
                }
            }
        }
        /** 每日总结 */
        printf("-*-星*期*%d*总*结-*-\n", day);
        printf("员工编号\t迟到\t早退\t旷工\t全勤\n");
        for(int i=0; i<STUFF; i++){
            printf("%s\t\t%d\t%d\t%d\t%d\n", ct[i].code, ct[i].L, ct[i].E, ct[i].X, ct[i].F);
        }
        day++;
    }
    printf("-*-*-周-*-总-*-结-*-*-\n", day);
    for(int i=0; i<STUFF; i++){
        ct[i].AVED = ct[i].D[0];
        for(int j=1; j<WEEKDAY; j++){
            ct[i].AVED += ct[i].D[j];
        }
        ct[i].AVED = ct[i].AVED *10/5;
    }
    printf("员工编号\t平均到岗时间\n");
    for(int i=0; i<STUFF; i++){
        printf("%s\t\t%d\n", ct[i].code, ct[i].AVED);
    }

    printf("回车\n");
    getchar();
    return;
}

/** 打卡程序 */
int CardOn(struct Info *ct, time_t tempClock)
{
    /** 设置缓冲区,比较符 */
    char tempCode[CD];
    printf("上班打卡模式\n");
    int bingo = 0;
    /** 打卡输入模块 */
    while(!bingo){
        time(&tempClock);
        printf("请输入工号:\n");
        gets(tempCode);
        for(int i=0; i<STUFF; i++){
            bingo = 1;
            for(int j=0; j<CD; j++){
                /** 若不匹配,则下一个 */
                if(tempCode[j]!=ct[i].code[j]){
                    bingo = 0;
                    break;
                }
            }
            /** 若完全匹配,则停止for循环 */
            if(bingo==1){
                if(ct[i].Schedule[0]!=0){
                    /** 重复打卡 */
                    printf("请勿重复打卡!\n");
                }else{
                    /** 首次打卡 */
                    ct[i].Schedule[0] = tempClock;
                    return i;
                }
                break;
            };
        }
        /** 查无此号:继续尝试or重新选择操作 */
        if(bingo==0){
            printf("不存在此工号\n");
            printf("是否退出?\n1.是\t0.否\n>>>");
            scanf("%d", &bingo);
            getchar();
            if(bingo==1) printf("退出成功\n");
        }
    }
    return -1;
}

/** 退卡程序 */
int CardOff(struct Info *ct, time_t tempClock)
{
    /** 设置缓冲区,比较符 */
    char tempCode[CD];
    printf("下班退卡模式\n");
    int bingo = 0;
    /** 退卡输入模块 */
    while(!bingo){
        time(&tempClock);
        printf("请输入工号:\n");
        gets(tempCode);
        for(int i=0; i<STUFF; i++){
            bingo = 1;
            for(int j=0; j<CD; j++){
                /** 不匹配则下一个 */
                if(tempCode[j]!=ct[i].code[j]){
                    bingo = 0;
                    break;
                }
            }
            /** 完全匹配 */
            if(bingo==1){
                /** 比打卡操作多了这一步 */
                if(ct[i].Schedule[0]==0){
                    printf("尚未打卡,强制退出!\n");
                }else{
                    if(ct[i].Schedule[1]!=0){
                        printf("请勿重复退卡!\n");
                    }else{
                        ct[i].Schedule[1] = tempClock;
                        return i;
                    }
                }

                break;
            };
        }
        if(bingo==0){
            printf("不存在此工号\n");
            printf("是否退出?\n1.是\t0.否\n>>>");
            scanf("%d", &bingo);
            getchar();
            if(bingo==1) printf("退出成功\n");
        }
    }
    return -1;
}

演示效果

---事先录入员工信息---
请输入1/3员工的工号:110000
请输入2/3员工的工号:110001
1/3员工的工号: 110000
2/3员工的工号: 110001
---星期 1---
!!!实际时间为: Sun Aug 30 10:34:32 2020

--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
$ 110000 号员工上班时间为  7 : 20,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110001
$ 110001 号员工上班时间为  8 : 10,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110001
$ 110001 号员工下班时间为  11 :  0,早退 310 分钟,予以警告!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110001
请勿重复退卡!
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
请勿重复打卡!
--*--1.打卡--*--2.退卡--*--
>>110002
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110002
不存在此工号
是否退出?
1.是    0.否
>>>0
请输入工号:
110003
不存在此工号
是否退出?
1.是    0.否
>>>1
退出成功
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110004
不存在此工号
是否退出?
1.是    0.否
>>>1
退出成功
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110000
$ 110000 号员工下班时间为  18 : 10,多工作 170 分钟,全勤鼓励!
-*-**1**-*-
员工编号        迟到    早退    旷工    全勤
110000          0       0       0       1
110001          0       1       0       0
---星期 2---
!!!实际时间为: Sun Aug 30 10:35:42 2020

--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110001
$ 110001 号员工上班时间为  8 : 30,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
$ 110000 号员工上班时间为  9 : 40,昨日加班,不算迟到。
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110001
$ 110001 号员工下班时间为  13 : 10,早退 200 分钟,予以警告!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110000
$ 110000 号员工下班时间为  17 : 40,多工作 0 分钟,全勤鼓励!
-*-**2**-*-
员工编号        迟到    早退    旷工    全勤
110000          0       0       0       2
110001          0       2       0       0
---星期 3---
!!!实际时间为: Sun Aug 30 10:36:48 2020

--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110001
$ 110001 号员工上班时间为  8 :  0,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
$ 110000 号员工上班时间为  9 : 40,上班迟到,予以警告!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110000
$ 110000 号员工下班时间为  14 : 10,早退 210 分钟,予以警告!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110001
$ 110001 号员工下班时间为  15 : 40,早退 20 分钟,予以警告!
-*-**3**-*-
员工编号        迟到    早退    旷工    全勤
110000          1       1       0       2
110001          0       3       0       0
---星期 4---
!!!实际时间为: Sun Aug 30 10:37:42 2020

--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110001
$ 110001 号员工上班时间为  31 : 10,上班迟到,予以警告!
Sun Aug 30 10:40:12 2020

PowerOff!
110000 号员工今日旷工
110001 号员工今日旷工
-*-**4**-*-
员工编号        迟到    早退    旷工    全勤
110000          1       1       1       2
110001          1       3       1       0
---星期 5---
!!!实际时间为: Sun Aug 30 10:40:12 2020

--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110001
$ 110001 号员工上班时间为  7 : 50,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
$ 110000 号员工上班时间为  9 :  0,今日按时到岗。
--*--1.打卡--*--2.退卡--*--
>>1
上班打卡模式
请输入工号:
110000
请勿重复打卡!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110000
$ 110000 号员工下班时间为  18 : 20,多工作 80 分钟,全勤鼓励!
--*--1.打卡--*--2.退卡--*--
>>2
下班退卡模式
请输入工号:
110001
$ 110001 号员工下班时间为  19 : 20,多工作 210 分钟,全勤鼓励!
-*-**5**-*-
员工编号        迟到    早退    旷工    全勤
110000          1       1       1       3
110001          1       3       1       1
-*-*--*--*--*-*-
员工编号        平均到岗时间
110000          392
110001          320
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 1024 设计师:白松林 返回首页