C++ 简易打卡机

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

在这里插入图片描述
一、变量设置

struct tm *info;  //当前时间(time.h内置结构体)

typedef struct WORKER{
    int number;    //员工编号
    int work_time;  //当天工作时间
    
    //上午上班时间
    string AM_ontime;   
    int AM_on_hour;
    int AM_on_mins;

    //上午下班时间
    string AM_outtime;  
    int AM_out_hour;
    int AM_out_mins;

    //下午上班时间
    string PM_ontime;   
    int PM_on_hour;
    int PM_on_mins;

    //下午下班时间
    string PM_outtime;  
    int PM_out_hour;
    int PM_out_mins;

    //晚上上班时间
    string Night_ontime;
    int Night_on_hour; 
    int Night_on_mins;

    //晚上下班时间  
    string Night_outtime; 
    int Night_out_hour; 
    int Night_out_mins;
}P;
P worker[5] = {0};  //员工结构体


//周报
struct REPORT
{
    int late_num; //迟到次数
    int early_num; //早退次数
    int absence_num; //缺勤次数
    double avetime; //周平均工作时间
}report[20] = {0};

二、主界面
先将所要完成的功能的整体框架写出来,然后一个一个去写具体的功能实现。

void clockin_machine_start()
{
    char select;
    string time = getTime();//当前时间


    //判断是否是休息日
    if(info->tm_wday >= 1 && info->tm_wday <= 5 )
    {
        printf("\n");
        printf("\n");
        printf("-----------------------------------\n");
        cout << "当前时间是:" ;
        cout << time << endl;
        cout << "打卡机已打开,请选择:" << endl;
        cout << "1.上班打卡" << endl;
        cout << "2.下班打卡" << endl;
        cout << "3.控制时间" << endl;
        cout << "4.生成周报" << endl;
        cout << "5.退出" << endl;

        cin >> select;
        if(select == '1')
        {
            create_checkNum();
        }
        else if(select == '2')
        {
            punch_card_out();
        }
        else if(select == '3')
        {
            control_time();
        }
        else if(select == '4')
        {
            create_report();
        }
        else if(select == '5')
        {
            exit(0);
        }
        else
        {
            printf("输入错误,请重新选择\n");
            clockin_machine_start();
        }
        
    }
    else
    {
        printf("今天是休息时间\n");
    }

}

三、获取和控制时间
要实现打卡,首先要获取当前的时间,该函数返回当前初始化的时间

int flag = 1;
string getTime()
{
    if(flag == 1)
    {
        time_t curtime;
        time( &curtime );
        info = localtime( &curtime );
        
        //初始化时间为星期一早上7点(没有初始化具体日期)
        info->tm_wday = 1;
        info->tm_hour = 7;
        info->tm_min = 0;
        info->tm_sec = 0;

        flag = 2;//仅初始化一次就行
    }
    char tmp[64];
    strftime(tmp, sizeof(tmp), "%A  %Y-%m-%d %H:%M:%S",info);
    return tmp;
}

然后对时间进行控制:

void control_time()
{
    //显示时间
    string time = getTime();
    printf("\n");
    printf("\n");
    printf("*****************************************\n");
    cout << "当前时间是:";
    cout << time << endl;

    char select;
    cout << "请选择:" << endl;
    cout << "1.时间增加一天(从另一天的早上七点开始)" << endl;
    cout << "2.时间增加几小时" << endl;
    cout << "3.返回" << endl;

    cin >> select;
    if(select == '1')
    {
        info->tm_wday = info->tm_wday + 1;
        info->tm_hour = 7;
        info->tm_min = 0;
        info->tm_sec = 0;
        control_time();
    }
    if(select == '2')
    {
        int hour;
        cout << "请输入增加的时间(小时):";
        cin >> hour;
        info->tm_hour = info->tm_hour + hour;
        control_time();
    }
    if(select == '3')
    {
        clockin_machine_start();
    }
}

要进行更具体的时间控制可根据tm结构体内部的参数进行修改

四、实现打卡
对时间进行控制后就要实现打卡。
先进行上班打卡:
上班打卡要输入员工编码,生成并检查效验码:

void create_checkNum()
{
    int N;//员工编号
    int ReNum = 0;//逆序
    int checkNum;//效验码


    //生成效验码
    printf("请输入员工编号(6位):\n");
    cin >> N;
    for(int i = 1; i <= 5; i++)
    {
        worker[info->tm_wday].number = N;       
    }

    //转化为逆序
    string Number = to_string(N);
    string ReNumber[5];
    for(int i = Number.size() - 1; i > 0; i--)
    {
        ReNumber[5-i] = Number[i];
    }

    for(int i = 0; i < 5; i++)
    {
        int a = stoi(ReNumber[i]);
        int b = 1;
        for(int j = 0; j < 4-i; j++)
        {
            b *= 10;
        }
        ReNum += a * b;
    }
    checkNum = ReNum + N;


    //检查效验码
    int CN;
    printf("请输入效验码:\n");
    cin >> CN;
    if(CN != checkNum)
    {
        printf("效验码错误,请重新输入.\n");
        create_checkNum();
    }
    else
    {
        printf("输入正确\n");
        punch_card_on();
    }
}

检查完后就进行上班打卡:
设置的上班时间分别为9:00 , 14:00 , 20:00

void punch_card_on()
{
    //上午
    if(info->tm_hour <= 12)
    {
        //9点上班
        if(info->tm_hour <= 9)
        {
            printf("上班打卡成功\n");
            worker[info->tm_wday].AM_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].AM_ontime << endl;  

            worker[info->tm_wday].AM_on_hour = info->tm_hour; //将小时(几点)存放到结构体
            worker[info->tm_wday].AM_on_mins = info->tm_min;   //将分钟(几分)存放到结构体

            clockin_machine_start();
        }

        //迟到
        else if(info->tm_hour < 11)
        {  
            printf("您已迟到\n");
            worker[info->tm_wday].AM_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].AM_ontime << endl; 

            worker[info->tm_wday].AM_on_hour = info->tm_hour; //将小时(几点)存放到结构体
            worker[info->tm_wday].AM_on_mins = info->tm_min;   //将分钟(几分)存放到结构体

            report[0].late_num ++;//迟到次数+1

            clockin_machine_start();
        }

        //超过规定时间(11点),认定缺勤
        else
        {
            printf("您被认为缺勤\n"); 

            clockin_machine_start();
        } 
    }


    //下午
    else if(info->tm_hour <= 19)
    {

        //2点上班
        if(info->tm_hour <= 14)
        {
            printf("上班打卡成功\n");
            worker[info->tm_wday].PM_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].PM_ontime << endl; 

            //将时间存放到结构体
            worker[info->tm_wday].PM_on_hour = info->tm_hour;
            worker[info->tm_wday].PM_on_mins = info->tm_min;

            clockin_machine_start();
        }
        else if(info->tm_hour < 17)
        {  
            printf("您已迟到\n");
            worker[info->tm_wday].PM_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].PM_ontime << endl; 

            //将时间存放到结构体
            worker[info->tm_wday].PM_on_hour = info->tm_hour;
            worker[info->tm_wday].PM_on_mins = info->tm_min;

            report[0].late_num ++;//迟到次数+1

            clockin_machine_start();
        }

        //超过下午五点,认为缺勤
        else 
        {
            printf("您被认为缺勤\n"); 

            clockin_machine_start();
        }     
    }


    //晚上
    else
    {
        //8点上班
        if(info->tm_hour <= 20 )
        {
            printf("上班打卡成功\n");
            worker[info->tm_wday].Night_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].Night_ontime << endl; 

            //将时间存放到结构体
            worker[info->tm_wday].Night_on_hour = info->tm_hour;
            worker[info->tm_wday].Night_on_mins = info->tm_min;

            clockin_machine_start();
        }
        else if(info->tm_hour <= 21)
        {  
            printf("您已迟到\n");
            worker[info->tm_wday].Night_ontime = getTime();
            cout << "打卡时间:" << worker[info->tm_wday].Night_ontime << endl; 

            //将时间存放到结构体
            worker[info->tm_wday].Night_on_hour = info->tm_hour;
            worker[info->tm_wday].Night_on_mins = info->tm_min;

            report[0].late_num ++;//迟到次数+1

            clockin_machine_start();
        }

        //超过晚上9点,认为缺勤
        else
        {
            printf("您被认为缺勤\n"); 

            clockin_machine_start();
        }        
    }    
}

上班打卡后就是下班打卡:
下班打卡就没有具体时间要求,最后工作时间足够就行。(但没打卡会被认为缺勤)

void punch_card_out()
{
    int N;
    printf("请输入您的编号:");
    cin >> N;

    //上午
    if(info->tm_hour < 13)
    {
        printf("下班打卡成功\n");
        worker[info->tm_wday].AM_outtime = getTime();
        cout << "打卡时间:" << worker[info->tm_wday].AM_outtime << endl;

        //将时间存放到结构体
        worker[info->tm_wday].AM_out_hour = info->tm_hour;
        worker[info->tm_wday].AM_out_mins = info->tm_min;

        //计算当天工作时间
        calculate_Worktime();
    }

    //下午
    else if(info->tm_hour < 19)
    {
        printf("下班打卡成功\n");
        worker[info->tm_wday].PM_outtime = getTime();
        cout << "打卡时间:" << worker[info->tm_wday].PM_outtime << endl;

        //将时间存放到结构体
        worker[info->tm_wday].PM_out_hour = info->tm_hour;
        worker[info->tm_wday].PM_out_mins = info->tm_min;

        //计算当天工作时间
        calculate_Worktime();
    }

    //晚上
    else 
    {
        printf("下班打卡成功\n");
        worker[info->tm_wday].Night_outtime = getTime();
        cout << "打卡时间:" << worker[info->tm_wday].Night_outtime << endl;

        //将时间存放到结构体
        worker[info->tm_wday].Night_out_hour = info->tm_hour;
        worker[info->tm_wday].Night_out_mins = info->tm_min;

        //计算当天工作时间
        calculate_Worktime();
    }
}

打卡完后进行计算工作时间的函数:

void calculate_Worktime()
{
    int am = 0;
    int pm = 0;
    int ni = 0;

    //上午工作时间
    //判断是否缺勤或没打卡
    if(worker[info->tm_wday].AM_on_hour != 0 && worker[info->tm_wday].AM_out_hour != 0)      
    {
        //计算时间
        am = (worker[info->tm_wday].AM_out_hour - worker[info->tm_wday].AM_on_hour) * 60
            + (worker[info->tm_wday].AM_out_mins - worker[info->tm_wday].AM_on_mins); 
    }
       

    //下午工作时间
    //判断是否缺勤或没打卡
    if(worker[info->tm_wday].PM_on_hour != 0 && worker[info->tm_wday].PM_out_hour != 0)
    {
        //计算时间
        pm = (worker[info->tm_wday].PM_out_hour - worker[info->tm_wday].PM_on_hour) * 60
            + (worker[info->tm_wday].PM_out_mins - worker[info->tm_wday].PM_on_mins); 
    }


    //晚上工作时间
    //判断是否缺勤或没打卡
    if(worker[info->tm_wday].Night_on_hour != 0 && worker[info->tm_wday].Night_out_hour != 0)
    {
        //计算时间
        ni = (worker[info->tm_wday].Night_out_hour - worker[info->tm_wday].Night_on_hour) * 60
            + (worker[info->tm_wday].Night_out_mins - worker[info->tm_wday].Night_on_mins); 
    }

    
    //将工作时间放入结构体
    int sum = am + pm + ni;
    worker[info->tm_wday].work_time = sum;


    //判断前一天是否加班超过3三小时
    int a = 540;
    if(worker[info->tm_wday - 1].work_time >= 720)
    {
        a = 420;
    }

    //如果小于规定工作时间
    if(sum < a)
    {
        int b = 540 - sum;
        printf("今天工作时间不足,早退%d分钟.\n", b);

        report[0].early_num ++; //早退次数+1
    }

    //如果满足工作时间
    else if(sum >= a && sum < 720)
    {
        printf("\n");
        printf("今天工作时间:%d分钟.\n", sum);
    }

    //返回主界面
    clockin_machine_start(); 
}

五、生成周报
只要一个时间段里仅打卡一次(仅上班打卡或仅下班打卡)都被认为缺勤

void create_report()
{
    double ave_time = 0;//周平均工作时间

    int sum = 0;
    for(int i = 1 ; i <= 5 ; i++)
    {
        sum += worker[i].work_time;
    }
    ave_time = sum / 5.0;
    report[0].avetime = ave_time;


    //统计缺勤次数
    for(int i = 1 ; i <= 5 ; i++)
    {
        //上午缺勤
        if(worker[i].AM_on_hour == 0 || worker[i].AM_out_hour == 0)
        {
            report[0].absence_num ++;
        }

        //下午缺勤
        if(worker[i].PM_on_hour == 0 || worker[i].PM_out_hour == 0)
        {
            report[0].absence_num ++;
        }

        //晚上缺勤
        if(worker[i].Night_on_hour == 0 || worker[i].Night_out_hour == 0)
        {
            report[0].absence_num ++;
        }
    }

    printf("\n");
    printf("**************周报*****************\n");
    printf("周平均工作时间: %lf分钟.\n", ave_time);
    printf("早退次数: %d\n", report[0].early_num);
    printf("迟到次数: %d\n", report[0].late_num);
    printf("缺勤次数: %d\n", report[0].absence_num);
    
}

六、主函数

int main()
{
    clockin_machine_start();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值