AIOT学习笔记(三)

新增打卡机任务

主要增加结构体数组\数组排序的内容

to be continued …

#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <sys/time.h>
#include <string.h>
#include <unistd.h>

//clock_t start_time1;
//clock_t end_time1;

#define WORKDAY 3
#define PROGRAMSTARTTIME 7.0 //程序开始时间为周一早上7点
#define WORKSTARTTIME 9 //上班时间
#define WORKENDTIME 18  //下班时间

//用于程序测试
#define HOUR_PER_SECOND 2 //测试时以2s表示一个小时
#define DAY_PER_HOUR 24 //测试时以24h表示一天

timeval program_start_time;
timeval program_end_time;

int date_count_hour=0,date_count_day = 0;

struct Staff_msg{
    char name[15];
    char sex[7];
    char phone[11];
    char mail[20];
};

typedef struct Struct_Staff{
    Staff_msg private_msg;
    char id[7];
    timeval in_time;
    timeval out_time;
    double workhour_count = 0;//mytimer1(in_time,out_time);
    int late_count = 0;//迟到
    int absence_count = 0;//缺勤
    int leave_early_count = 0;//早退
    int late_date[WORKDAY];//记录对应的时间
    int absence_date[WORKDAY];
    int leave_early_date[WORKDAY];
    int check1 = 0;//正常上班打卡check
    int check2 = 0;//不正常上班打卡check
    int check3 = 0;//不正常下班打卡check
    int check4 = 0;//正常下班打卡check
    int check5 = 0;//弹性打卡check
}SS;

SS staff[20];

void log_in()
{
    strcpy(staff[0].id,"123456");
    strcpy(staff[0].private_msg.name,"张三");
    strcpy(staff[1].id,"111111");
    strcpy(staff[1].private_msg.name,"李四");
    strcpy(staff[2].id,"122222");
    strcpy(staff[2].private_msg.name,"王五");
}

void printWorkMsg(SS staffx)
{
    printf( "Staff id : %s\n", staffx.id);
    printf( "Average work time : %.2f\n",staffx.workhour_count/WORKDAY);
    printf( "Late : %d\n", staffx.late_count);
    printf( "Absence : %d\n", staffx.absence_count);
    printf( "Early Leave : %d\n\n", staffx.leave_early_count);
}
void printRewardList()
{
    printf("奖励名单\n");
    for(int i=0;i<3;i++)
    {
        if(staff[i].late_count == 0 && staff[i].leave_early_count == 0 && staff[i].absence_count == 0)
        {
            printf("%s获全勤奖\n",staff[i].private_msg.name);
        }

    }
}


SS *sortWorkTime(SS *staff)
{
    SS *arr[20];
    for(int t=0;t<20;t++)
        arr[t] = staff + t;
    for(int i = 0; i < 20; i++)
    {
        for(int j = 0; j < 20 - i; j++)
        {
            if(arr[j]->workhour_count > arr[j+1]->workhour_count)
            {// 相邻元素两两对比
                SS *temp = arr[j+1];
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr[0];
}

void printPunishList()
{
    printf("惩罚名单\n");
    SS temp =  *sortWorkTime(&staff[0]);
    for(int j=3;j>0;j--)
        printf("惩罚:%s,原因:\n",((&temp + j)->id));
}
//计时函数clock() 经测试发现该计时方法不准
/*
void mytimer(clock_t start_time1,clock_t end_time1)
{
    start_time=clock();		//程序开始计时
    int ans=0;
    for(int i=1;i<=1e8;i++)
        ans++;
    end_time=clock();		//程序结束用时
    double total_time=(double)(end_time1-start_time1)/CLOCKS_PER_SEC;
    cout<<"Total time:"<<total_time<<"s"<<endl;		//s为单位
    cout<<"Total time:"<<total_time*1000<<"ms"<<endl;	//ms为单位
    //system("pause");
};
*/
//计时函数gettimeofday
double mytimer1(timeval start_time,timeval end_time)
{    
    //timeval start_time, end_time;
    //gettimeofday(&start_time, NULL);
    //gettimeofday(&end_time, NULL);
    double second = (end_time.tv_sec - start_time.tv_sec) +
            (end_time.tv_usec - start_time.tv_usec)/1e6;
    //1秒一个小时,24小时一天
    date_count_hour = second / HOUR_PER_SECOND;
    date_count_day = date_count_hour / DAY_PER_HOUR ;
    return date_count_hour;
};

//判断编号是否符合规范
//及匹配到人to do
int judge_Verification(char *p)
{
    char s[7]={0};
    strcpy(s,p);
    int i = strlen(s);
    int flag = 0;
    for(int j=0;j<20;j++)//查找有无该ID
    {
        if(strcmp(s,staff[j].id)==0)
        {
            flag = 1;
            break;
        }
    }

    if(i==6 && s[0]=='1' && flag)
    {
        printf("员工编号正确\n");
        return 1;
    }
    else
    {
        printf("员工编号错误\n");
        return 0;
    }
};
//校验码检查函数
int Verification(char *p1,char *p2)
{
    char s[7];
    for(int i=0;i<6;i++)
    {
        s[i] = *p1;
    }
    //s数组反序
    for(int i=1;i<6;i++)
    {
        s[i]=*(p1+6-i);
    }
    //新数组
    for(int i=1;i<6;i++)
    {
        //ASCII码 数字'0'编号为48,减48或'0'
        s[i]+=*(p1+i)-'0';
    }
    if(strcmp(s,p2)==0) return 1;
    else return 0;
};

//根据输入的id匹配员工
SS *match(char number[7])
{
    for(int i=0;i<20;i++)
    {
        if(strcmp(number,staff[i].id)==0)
        {
//            printf("i:%d\n",i);
//            printf("输入的id:%s\n",number);
//            printf("匹配的id:%s\n",staff[i].id);
//            printf("匹配的地址:%p\n",&staff[i]);
            return &staff[i];
        }
    }
};
void clock_in(double time_cpy)    //上班打卡
{
    int flag = 1;
    char number[7] = {0};
    while(flag)
    {
        printf("请输入员工编号\n");
        gets(number);
        if(judge_Verification(number))
        {
            flag = 0;
        }
    }
    char check[7] = {0};
    flag = 1;
    while(flag)
    {
        printf("请输入校验码\n");
        gets(check);
        if(Verification(number,check))
        {
            flag = 0,printf("上班打卡成功\n\n");
            SS *staffx;
            staffx = match(number);
            gettimeofday(&(staffx->in_time), NULL);
            if(staffx->check5 == 1)
            {
                //弹性打卡
                if(time_cpy<WORKSTARTTIME+2) staffx->check1 = 1;
                else if(time_cpy>WORKSTARTTIME+2 && time_cpy<WORKENDTIME) staffx->check2 = 1;
                staffx->check5 = 0;
            }
            else
            {
                if(time_cpy<WORKSTARTTIME) staffx->check1 = 1;//正常上班
                else if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staffx->check2 = 1;//迟到
            }

        }
        else printf("校验码错误\n\n");
    }
}

void clock_out(double time_cpy)//下班打卡
{
    char number[7] = {0};
    int flag = 1;
    while(flag)
    {
        printf("请输入员工编号\n");
        gets(number);
        if(judge_Verification(number))
        {
            flag = 0;
        }
        //else judge_Verification();
    }
    SS *staffx;
    staffx = match(number);
    printf("下班打卡成功\n\n");
    if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staffx->check3 = 1;
    else if(time_cpy>WORKENDTIME) staffx->check4 = 1;
    gettimeofday(&staffx->out_time, NULL);
    staffx->workhour_count += mytimer1(staffx->in_time,staffx->out_time);
}

void clockin_machine_start()    //打卡机
{
    //开启打卡机
    printf("输入1开启打卡机\n");
    int flag = 1;
    while(flag)
    {
        char s = getchar();
        char ss = getchar();//存入换行符
        if(s == '1')
        {
            flag = 0;
            printf("打卡机已开启\n");
            gettimeofday(&program_start_time, NULL);
        }
        else printf("指令错误,输入1开启打卡机\n");
    }

    log_in();
    //start_time1 = clock();
    //程序总的运行时间
    double time = PROGRAMSTARTTIME;//此处必须刷新一次即输入3,再打卡为正确时间
    do{
        //所有时间单位为h
        int time_cpy = (int)time % DAY_PER_HOUR;//打卡机当前时间
        int time_cpy2 = time / DAY_PER_HOUR;//打卡机工作了几天

        while(time_cpy<=WORKSTARTTIME)
        {
            //上班打卡
            printf("上班时间\n");
            printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
            //记录每个人的上班打卡时间,并且令check1 = 1
            //若该段时间没有打卡,check1 = 0
            printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n");
            char s = getchar();
            char ss = getchar();//存入换行符

            switch (s)
            {
                case '1':{
                    printf("上班打卡\t");
                    printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
                    clock_in(time_cpy);
                    break;
                }
                case '2':{
                    printf("该时间无法下班打卡\n");
                    break;
                }
                default:{
                    printf("\n");break;
                }
            }
            break;
        }
        while(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME)
        {
            printf("工作时间\n");
            printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
            printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n");
            char s = getchar();
            char ss = getchar();//存入换行符
            switch (s)
            {
                case '1':{
                    printf("上班打卡\t");
                    printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
                    clock_in(time_cpy);
                    break;
                }
                case '2':{
                    printf("下班打卡\t");
                    printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
                    clock_out(time_cpy);
                    break;
                }
                default:{
                    printf("\n");break;
                }
            }
            for(int i=0;i<3;i++)//只录入三个人用于测试
            {
                //若check1 == 0,该时间段打卡,则为迟到
                if(staff[i].check2 ==1)
                    staff[i].late_date[staff[i].late_count] = time_cpy2,staff[i].late_count += 1;
                //若check1 == 0,该时间段未打卡,在下班时间后记录为缺勤
                //若check1 == 1,该时间段打卡记为早退
                if(staff[i].check1 == 1 && staff[i].check3 == 1)
                    staff[i].leave_early_date[staff[i].leave_early_count] = time_cpy2,staff[i].leave_early_count += 1;
            }
            break;
        }
        while(time_cpy>=WORKENDTIME)
        {
            printf("下班时间\n");
            printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
            //记录缺勤
            for(int i=0;i<3;i++)//3个人
            {
                if(staff[i].check1 == 0 && staff[i].check2 ==0)
                    staff[i].late_date[staff[i].late_count] = time_cpy2,staff[i].absence_count += 1;
            }
            //下班打卡时间
            printf("输入1上班打卡,输入2下班打卡,输入其他刷新\n");
            char s = getchar();
            char ss = getchar();//存入换行符

            switch (s)
            {
                case '1':{
                    printf("当前无法上班打卡\t");
                    printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
                    break;
                }
                case '2':{
                    printf("下班打卡\t");
                    printf("当前时间:周%d, %d点\n",time_cpy2+1,time_cpy);
                    clock_out(time_cpy);
                    break;
                }
                default:{
                    printf("\n");break;
                }
            }
            break;
        }
        //每经过一天的操作
        while(time_cpy2>1)
        {
            //忘记下班打卡,记录为缺勤
            for(int i=0;i<20;i++)
            {
                if((staff[i].check1 == 1 || staff[i].check2 == 1) && (staff[i].check3 == 0 || staff[i].check4 == 0))
                {
                    //staff[i].workhour_count += 0;
                    staff[i].absence_count += 1;
                }
            //弹性打卡制,若前一天上班时长超过规定时长3小时以上,第二天迟到2小时以内不算迟到
                if(mytimer1(staff[i].in_time,staff[i].out_time)-3>=(WORKSTARTTIME-WORKENDTIME))
                {
                    staff[i].check5 = 1;
                }
                //状态归零
                    staff[i].check1 = 0;
                    staff[i].check2 = 0;
                    staff[i].check3 = 0;
                    staff[i].check4 = 0;
            }

            break;
        }

        gettimeofday(&program_end_time, NULL);
        time = mytimer1(program_start_time,program_end_time) + PROGRAMSTARTTIME;
    }while(time < DAY_PER_HOUR * WORKDAY);
    //打印员工的打卡信息
    printf("*******************************\n"
            "考勤周报\n\n");
    for(int i=0;i<3;i++)
        printWorkMsg(staff[i]);
    printf("*******************************\n\n");

    //打印奖惩信息
    printf("*******************************\n");
    printRewardList();
    printPunishList();
    printf("*******************************\n");

}

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值