天天看點

AIoT學習筆記(二)打卡機核心功能實作:我的代碼:全部代碼如下其它問題

打卡機核心功能實作:

應市場需求,某工程師現設計了一款新上下班打卡機,打卡機具有以下功能:

(1) 上班打卡,員工具有編号(首位為 1 的六位編号),輸入編号後,再 輸入校驗碼,校驗碼生成規則:員工編号除首位反序,再與員工編号 求和,如:員工編号,110086,校驗碼為 178087。校驗碼錯誤即打 卡失敗。記錄打卡時間

(2) 下班打卡,隻需輸入員工編号即可。記錄打卡時間,顯示該人員今天上班時長,如果上班時長不夠,顯示早退 xx 分鐘。可以更新下班打卡時間。無下班打卡顯示缺卡。

(3) 可以設定規定上班時長,如 9 小時

(4) 測試需要可以規定 6 秒=實際 1 小時,每次測試,輸入指令後,開啟 打卡機,打卡機開啟模拟時間為:周一早上七點。程式運作結束為周五晚 12 點。

(5) 實行彈性打卡制,如前一天上班時長超過規定時長 3 小時以上,第 二天遲到 2 小時以内不算遲到。

(6) 打卡機運作結束之前,每周該打卡機會生成每周考勤周報,顯示周平 均上班時長,周遲到,早退,缺卡次數等。

我的代碼:

問題:

<time.h>中的計時函數clock() 經測試發現該計時方法不準

改用<.ctime>中的gettimeofday()實作,是以雖然是c代碼,程式的字尾名需要為*.cpp

to do:

1.bug

在do while循環中第一次循環,time等于設定的初值7,是以第一次打卡的時間始終為早上七點,

此處必須重新整理一次,即輸入1或2之外的其他值,使其結束第一次循環,此時打卡為正确時間。

2.多員工打卡

思路:對于多個員工的打卡,已經定義了staff的結構體,考慮輸入員工id時與struct中的id進行對比,傳回對應的struct指針,完成id和員工的比對。

struct staff{
    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 check1 = 0;//正常上班打卡check
    int check2 = 0;//不正常上班打卡check
    int check3 = 0;//不正常下班打卡check
    int check4 = 0;//正常下班打卡check
    int check5 = 0;//彈性打卡check
};
           

3.優化

備援的一些代碼可以寫成函數,比如列印時間

printf("工作時間\n");
printf("目前時間:周%d, %d點\n",time_cpy2+1,time_cpy);
printf("輸入1上班打卡,輸入2下班打卡,輸入其他重新整理\n");
           

全部代碼如下

#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 WORKHOUR 9
#define PROGRAMSTARTTIME 7.0 //程式開始時間為周一早上7點
#define WORKSTARTTIME 9 //上班時間
#define WORKENDTIME 18  //下班時間

//用于程式測試
#define HOUR_PER_SECOND 1 //測試時以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{
    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 check1 = 0;//正常上班打卡check
    int check2 = 0;//不正常上班打卡check
    int check3 = 0;//不正常下班打卡check
    int check4 = 0;//正常下班打卡check
    int check5 = 0;//彈性打卡check
};

staff staff1,staff2,staff3;

void log_in()
{
    strcpy(staff1.id,"123456");
    strcpy(staff2.id,"110086");
    strcpy(staff3.id,"168001");
}

void printStaff(struct staff 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( "Learly Leave : %d\n", staffx.leave_early_count);
}
//計時函數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);
    if(i==6 && s[0]=='1')
    {
        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;
};

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;
        }
        //else judge_Verification();
    }
    char check[7] = {0};
    flag = 1;
    while(flag)
    {
        printf("請輸入校驗碼\n");
        gets(check);
        if(Verification(number,check))
        {
            flag = 0,printf("上班打卡成功\n\n");
            gettimeofday(&staff1.in_time, NULL);
            if(staff1.check5 == 1)
            {
                //彈性打卡
                if(time_cpy<WORKSTARTTIME+2) staff1.check1 = 1;
                else if(time_cpy>WORKSTARTTIME+2 && time_cpy<WORKENDTIME) staff1.check2 = 1;
                staff1.check5 = 0;
            }
            else
            {
                if(time_cpy<WORKSTARTTIME) staff1.check1 = 1;//正常上班
                else if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staff1.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();
    }
    printf("下班打卡成功\n\n");\
    if(time_cpy>WORKSTARTTIME && time_cpy<WORKENDTIME) staff1.check3 = 1;
    else if(time_cpy>WORKENDTIME) staff1.check4 = 1;
    gettimeofday(&staff1.out_time, NULL);
    staff1.workhour_count += mytimer1(staff1.in_time,staff1.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;//存在bug,第一次打卡的時間始終為早上七點,此處必須重新整理一次即輸入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;
                }
            }
            //若check1 == 0,該時間段打卡,則為遲到
            if(staff1.check2 ==1) staff1.late_count += 1;
            //若check1 == 0,該時間段未打卡,在下班時間後記錄為缺勤
            //若check1 == 1,該時間段打卡記為早退
            if(staff1.check1 == 1 && staff1.check3 == 1) staff1.leave_early_count += 1;
            break;
        }
        while(time_cpy>=WORKENDTIME)
        {
            printf("下班時間\n");
            printf("目前時間:周%d, %d點\n",time_cpy2+1,time_cpy);
            //記錄缺勤
            if(staff1.check1 == 0 && staff1.check2 ==0) staff1.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)
        {
            //忘記下班打卡,記錄為缺勤
            if((staff1.check1 == 1 || staff1.check2 == 1) && staff1.check3 == 0 && staff1.check4 == 0)
            {
                staff1.workhour_count += 0;
                staff1.absence_count += 1;
            }
            //狀态歸零
            staff1.check1 = 0;
            staff1.check2 = 0;
            staff1.check3 = 0;
            staff1.check4 = 0;

            //彈性打卡制,若前一天上班時長超過規定時長3小時以上,第二天遲到2小時以内不算遲到
            if(mytimer1(staff1.in_time,staff1.out_time)-3>=(WORKSTARTTIME-WORKENDTIME))
            {
                staff1.check5 = 1;
            }
            break;
        }

        gettimeofday(&program_end_time, NULL);
        time = mytimer1(program_start_time,program_end_time) + PROGRAMSTARTTIME;
    }while(time < DAY_PER_HOUR * WORKDAY);
    //列印員工的打卡資訊
    printStaff(staff1);
    //printStaff(staff2);
    //printStaff(staff3);
}


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

           

其它問題

編寫部落格的時候發現的問題

輸入的ctime顯示不出來

原因:所有“< >"之間的内容都會被預設被HTML的标簽而不予顯示。此時,就需要使用轉義字元以示差別, " <“使用”<“代替,而”>“則使用”>"代替

AIoT學習筆記(二)打卡機核心功能實作:我的代碼:全部代碼如下其它問題

繼續閱讀