C語言 打卡機
阿新 • • 發佈:2020-09-07
#include<stdio.h> #include<stdlib.h> #include<string> #include<ctime> #include<unistd.h> //sleep函式的標頭檔案 #include<sys/time.h> //gettimeofday(struct timeval * tv, struct timezone * tz)計時函式 #include<pthread.h> //多執行緒標頭檔案 #define standard_Worktime 9.0 #defineMAX 20 void clear(); //清屏函式 void clockin_machine_start(); //打卡機執行計時函式 void showMenu(); //主介面 void judge_punch(); //判斷上班打卡和下班打卡 void morning_punch(struct staff*); //上班打卡 void night_punch(struct staff*); //下班打卡 void punch_list(struct staff*); //打卡記錄表 void lack_punch(struct staff*); //缺卡記錄函式 struct punch_clock{ int number_arr[6]; int sum_arr = 0; //判斷重複打卡正確是否的變數 int check_arr[6]; timeval Punch_startTime; //上班打卡時刻 char start_flag = 'F'; //上班打卡標記 int late_number = 0; //遲到次數 timeval Punch_endTime; //下班打卡時刻 char end_flag = 'F'; //下班打卡標記 int early_number = 0; //早退次數 int lack_number = 0; //缺卡次數 float Punch_timeuse; //上班耗時 }; punch_clock punch_number; struct staff{ //員工類 punch_clock Staff_Array[MAX]; int size=1; }; staff staff_num; struct machine_time{ int num_week=1; //第幾周,周幾,幾點 int week=1; //初始時間為第一週週一早上7點 int time=7; timeval startTime; //打卡機開始工作時刻 timeval endTime; //打卡機目前工作時刻 float timeuse; //機器執行時長 }; machine_time machineTime; void clear(){ getchar(); system("clear"); fflush(stdin); } //打卡機執行計時函式 void *clockin_machine_start(void *arg){ gettimeofday(&machineTime.startTime,NULL); while (1){ sleep(1); gettimeofday(&machineTime.endTime,NULL); if (0 == ((int)(machineTime.endTime.tv_sec-machineTime.startTime.tv_sec))%6){ machineTime.time++; if (0==((int)machineTime.time%24)){ machineTime.time=0; machineTime.week++; lack_punch(&staff_num); if ((5 == ((int)machineTime.week)) && (24 == ((int)machineTime.time))){ punch_list(&staff_num); //測試在週五晚上12點結束測試結束自動列印本週的報告 break; } if (0==((int)machineTime.week%7)){ machineTime.week=1; machineTime.num_week++; } } } } return NULL; } //缺卡記錄函式 void lack_punch(staff *staff_num){ for (int i = 1; i <= staff_num->size; i++){ if ('F' != staff_num->Staff_Array[i].start_flag){ if ('F' == staff_num->Staff_Array[i].end_flag){ staff_num->Staff_Array[i].lack_number++; } } } } //打卡機主介面 void showMenu(){ printf(" **********************\n"); printf(" **********************\n"); printf(" ****** 打卡機 ******\n"); printf(" **********************\n"); printf(" **********************\n"); printf(" 第%d周 星期%d %d時\n",machineTime.num_week,machineTime.week,machineTime.time); printf(" ----------------------\n"); } //打卡記錄表 void punch_list(staff *staff_num){ showMenu(); if (1 == staff_num->size) { printf("當前沒有打卡記錄\n"); } else{ for(int i=1;i<(staff_num->size);i++){ printf(" ----------------------\n"); printf("員工編號:%d\n",staff_num->Staff_Array[i].sum_arr); printf("周平均上班時長%.1f\n",staff_num->Staff_Array[i].Punch_timeuse/5.0); printf("周遲到次數%d\n",staff_num->Staff_Array[i].late_number); printf("周早退次數%d\n",staff_num->Staff_Array[i].early_number); printf("周卻卡次數%d\n",staff_num->Staff_Array[i].lack_number); } } clear(); } //判斷上下班打卡 void judge_punch(){ showMenu(); printf("1(上班打卡)\t2(下班打卡)\n"); int choice_1; scanf("%d",&choice_1); clear(); switch (choice_1){ case 1:{ morning_punch(&staff_num); break; } case 2: { night_punch(&staff_num); break; } } } //上班打卡 void morning_punch(staff *staff_num){ showMenu(); if (MAX == staff_num->size) //判斷打卡機是否還有儲存空間 { printf("打卡機容量已滿\n"); } staff_num->Staff_Array[staff_num->size].number_arr[0]=1; //所有員工第一位的編碼都是1 printf("請輸入你編號的後五位\n"); int number; scanf("%d",&number); clear(); staff_num->Staff_Array[staff_num->size].number_arr[1]=number/10000; staff_num->Staff_Array[staff_num->size].number_arr[2]=(number-staff_num->Staff_Array[staff_num->size].number_arr[1]*10000)/1000; staff_num->Staff_Array[staff_num->size].number_arr[3]=(number-staff_num->Staff_Array[staff_num->size].number_arr[1]*10000-staff_num->Staff_Array[staff_num->size].number_arr[2]*1000)/100; staff_num->Staff_Array[staff_num->size].number_arr[4]=(number-staff_num->Staff_Array[staff_num->size].number_arr[1]*10000-staff_num->Staff_Array[staff_num->size].number_arr[2]*1000-staff_num->Staff_Array[staff_num->size].number_arr[3]*100)/10; staff_num->Staff_Array[staff_num->size].number_arr[5]=number-staff_num->Staff_Array[staff_num->size].number_arr[1]*10000-staff_num->Staff_Array[staff_num->size].number_arr[2]*1000-staff_num->Staff_Array[staff_num->size].number_arr[3]*100-staff_num->Staff_Array[staff_num->size].number_arr[4]*10; showMenu(); printf("你的編號是:"); for(int i = 0; i < sizeof(staff_num->Staff_Array[staff_num->size].number_arr)/sizeof(staff_num->Staff_Array[staff_num->size].number_arr[0]); i++){ printf("%d",staff_num->Staff_Array[staff_num->size].number_arr[i]); } printf("\n"); //判斷是否有重複打卡 int flag = 0; for (int i = 1; i <= MAX; i++){ if(number == staff_num->Staff_Array[i].sum_arr){ flag = 1; } } if (1 == flag){ printf("你今天上班已經打過卡了\n"); clear(); } else{ //打卡重複記錄 staff_num->Staff_Array[staff_num->size].sum_arr = number+100000; int start=1;//效驗碼計算 int end=(sizeof(staff_num->Staff_Array[staff_num->size].number_arr)/sizeof(staff_num->Staff_Array[staff_num->size].number_arr[0]))-1; for(int i=0;i<sizeof(staff_num->Staff_Array[staff_num->size].number_arr)/sizeof(staff_num->Staff_Array[staff_num->size].number_arr[0]);i++){ //將編號陣列賦值給效驗碼陣列 staff_num->Staff_Array[staff_num->size].check_arr[i] = staff_num->Staff_Array[staff_num->size].number_arr[i]; } //效驗碼計算得到效驗碼 while (start<end){ int temp = staff_num->Staff_Array[staff_num->size].check_arr[start]; staff_num->Staff_Array[staff_num->size].check_arr[start]=staff_num->Staff_Array[staff_num->size].check_arr[end]; staff_num->Staff_Array[staff_num->size].check_arr[end]=temp; start++; end--; } //將效驗碼轉換為一個數 int sum= 100000+(staff_num->Staff_Array[staff_num->size].number_arr[1]+ staff_num->Staff_Array[staff_num->size].check_arr[1])*10000+ (staff_num->Staff_Array[staff_num->size].number_arr[2]+ staff_num->Staff_Array[staff_num->size].check_arr[2])*1000+ (staff_num->Staff_Array[staff_num->size].number_arr[3]+ staff_num->Staff_Array[staff_num->size].check_arr[3])*100+ (staff_num->Staff_Array[staff_num->size].number_arr[4]+ staff_num->Staff_Array[staff_num->size].check_arr[4])*10+ (staff_num->Staff_Array[staff_num->size].number_arr[5]+ staff_num->Staff_Array[staff_num->size].check_arr[5]); printf("請輸入你的效驗碼:\n"); int check_number; scanf("%d",&check_number); clear(); //判斷效驗碼 if(check_number==sum){ showMenu(); printf("打卡成功\n"); gettimeofday(&staff_num->Staff_Array[staff_num->size].Punch_startTime,NULL);//記錄開工時間 staff_num->Staff_Array[staff_num->size].start_flag = 'T'; //上班打卡標記 if (9.0 < machineTime.time){ //判斷是否遲到 設定9點為標準上班時間 staff_num->Staff_Array[staff_num->size].late_number++; } staff_num->size++; //記錄這個打卡的員工 clear(); } else{ staff_num->Staff_Array[staff_num->size].sum_arr=0; //打卡失敗則該值置零 printf("打卡失敗\n"); clear(); } } } void night_punch(staff *staff_num){ //下班打卡 showMenu(); printf("請輸入你的編號\n"); //下班員工編碼輸入陣列 int night_number_arr; scanf("%d",&night_number_arr); clear(); int ret = 0; //判斷是否有上班打卡 for (int i = 1; i < MAX; i++){ if (night_number_arr == staff_num->Staff_Array[i].sum_arr){ ret = 1; } } if (0 == ret){ showMenu(); printf("打卡失敗!編號%d今天沒有上班\n",night_number_arr); clear(); } else{ if (night_number_arr==staff_num->Staff_Array[ret].sum_arr){ showMenu(); gettimeofday(&staff_num->Staff_Array[ret].Punch_endTime,NULL); staff_num->Staff_Array[ret].Punch_timeuse = (staff_num->Staff_Array[ret].Punch_endTime.tv_sec-staff_num->Staff_Array[ret].Punch_startTime.tv_sec)/6.0; if(staff_num->Staff_Array[ret].Punch_timeuse < standard_Worktime){ printf("打卡成功\n"); printf("今日早退:%.1f小時\n",(standard_Worktime-staff_num->Staff_Array[ret].Punch_timeuse)); //下班打卡計時 staff_num->Staff_Array[ret].end_flag = 'T'; //下班打卡標記 staff_num->Staff_Array[ret].early_number++; clear(); } else{ printf("打卡成功\n"); printf("今日已加班:%.1f小時\n",(standard_Worktime-staff_num->Staff_Array[ret].Punch_timeuse)); staff_num->Staff_Array[ret].end_flag = 'T'; //下班打卡標記 clear(); } } else{ printf("打卡失敗\n"); clear(); } } } int main(){ pthread_t id; pthread_create(&id,NULL,clockin_machine_start,NULL); //打卡機時間開始啟動 while (1){ showMenu(); //主介面顯示啟動 printf(" 是否需要打卡:\n1(是) 2(打卡記錄) 3(退出)\n"); //判斷是否需要打卡 int choice; scanf("%d",&choice); clear(); switch (choice){ case 1: judge_punch(); break; case 2: punch_list(&staff_num); break; case 3: printf("感謝使用\n"); clear(); return 0; } } pthread_join(id,NULL); return 0; }