自己早期写的一个简单上下班打卡统计工时的考勤系统【整理版】
2012-06-29 10:58
399 查看
原本这个帖子,是由回复组成的,整个代码分布在各个回复里面,读者不好阅读,现在整个把它们放到正文,方便查看。
这是早期写的一个,仅仅是简单的考勤系统,大致功能是有的,但并未写的很牛叉,采用了文本来记录考勤数据,供小菜一览。
以下内容全部为一个c文件(主c文件),其实也就只有这个c文件。加上上面的头文件,整个可以编译通过生成我们的考勤系统。只是因为CSDN的语法高亮做的不好,如果代码太长的话,整个网页加载起来很慢,所以就分开为几小段了。
另外关于输入检查这一块,之前没有写一个函数,结果这个程序只能固定多少个字符,来进行偏移,少了不行,多了也不行,全都是用指针偏移来操作的。后来写了个函数(请参考从符号分隔的命令行获取任意参数的函数(逗号分隔,空格分隔等都可以)(2011-12-29
01:04)) ,但是,由于太懒,所以没有改写这个考勤系统。留给读者改改吧。
这是早期写的一个,仅仅是简单的考勤系统,大致功能是有的,但并未写的很牛叉,采用了文本来记录考勤数据,供小菜一览。
//头文件:emp_head.h #ifndef EMP_HEAD_H #define EMP_HEAD_H #include<stdio.h> #include<stdlib.h> #define MAXNUM 1000 enum { NORMAL = 0, ABSENT = 1, WORK_LATE = 2, LE***E_EARLY = 3, LATE_AND_LEARLY = 4, PUNCH_ABNORMAL = 5 }; enum { ERR_TIME_INVALID = 1, ERR_ID_INVALID = 2, ERR_CMD_INVALID = 3, ERR_EXIT_SYS = 9 }; struct emp_data { int id; char name[8]; int type; char check_in[16];//19:58 20110804 char check_out[16]; int work_time; //1208 --> 12H12M } emp_data1; int cmd_process(char* cmdx); void p_err(int err); int check_time(char *time); int check_type(char *check_in, char *check_out); void th_func(void); void print_help(void); int clean_data(char *fileaddr); int request_data(char *fileaddr, char* cmdx); int check_inout(char *fileaddr, char* cmdx); int type_check(char* check_in, char *check_out, int* outlen); char* ret_typestr(int typecode); //char* analy_cmd(char* cmdx, int* n); #endif //end EMP_HEAD_H
以下内容全部为一个c文件(主c文件),其实也就只有这个c文件。加上上面的头文件,整个可以编译通过生成我们的考勤系统。只是因为CSDN的语法高亮做的不好,如果代码太长的话,整个网页加载起来很慢,所以就分开为几小段了。
另外关于输入检查这一块,之前没有写一个函数,结果这个程序只能固定多少个字符,来进行偏移,少了不行,多了也不行,全都是用指针偏移来操作的。后来写了个函数(请参考从符号分隔的命令行获取任意参数的函数(逗号分隔,空格分隔等都可以)(2011-12-29
01:04)) ,但是,由于太懒,所以没有改写这个考勤系统。留给读者改改吧。
/* *主c文件 *author:duanxufang *time: *description:考勤系统 * */ #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <string.h> #include "../include/emp_head.h" #define FILE_IN "emp_record.datafile" struct emp_data record[MAXNUM] = {0}; int main() { pthread_t th_id; printf("will create thread!\n"); if(pthread_create(&th_id, NULL, (void*)th_func, NULL)) { printf("create thread error!\n"); exit(1); } if(pthread_join(th_id, NULL)) { printf("thread quit error!"); exit(1); } return 0; }
void p_err(int err) { switch(err) { case ERR_TIME_INVALID : printf("[ERR:TIME INVALID]\n"); break; case ERR_ID_INVALID : printf("[ERR:ID INVALID]\n"); break; case ERR_CMD_INVALID : printf("[ERR:COMMAND INVALID]\n"); break; case 0 : break; default: printf("ERR:Not Known!\n"); } return ; } void th_func(void) { char input_cmd[256] = {0}; print_help(); while(printf("cmd here>"),gets(input_cmd)) { int err_no = 0; if((err_no = cmd_process(input_cmd)) == ERR_EXIT_SYS) { printf("EXIT SYSTEM\n"); break; } p_err(err_no); printf("\nplease input next cmd:\n"); } return ; } void print_help(void) { printf("--------cmd help:-----------\n\"0\":clean all the records \"1\":checktime input\n"); printf("\"2\":request records q/Q for quit system\n"); printf("h/H for help\n"); printf("cmd format is: 1,0001,duan001,18:56\n \ [id] like 0001 must be 4 chars\n \ [name] like duan001 must be 7 chars\n"); printf("--------cmd help end--------\n"); return ; } int cmd_process(char* cmdx) { printf("Your cmd: %s\n", cmdx); int cmd_id = (int)(cmdx[0]-'0'); switch(cmd_id) { case 0: clean_data(FILE_IN); break; case 1: check_inout(FILE_IN, cmdx); break; case 2: request_data(FILE_IN, cmdx); break; case 'h'-'0': case 'H'-'0': print_help(); break; case 'q'-'0': case 'Q'-'0': return ERR_EXIT_SYS; //quik system; default: return ERR_CMD_INVALID; } return 0; } int clean_data(char *fileaddr) { int count = 0; char buf[60000]; int read_n = 0; int i = 0; struct emp_data *pemp = (struct emp_data *)buf; FILE *fptr; printf("clean_data()\n");//for debug if(!(fptr = fopen(FILE_IN, "w")) ) { printf("in clean _data open file[%s] failed!\n", FILE_IN); return 1; } if(!(read_n = fread(buf, 1, 60000, fptr))) { printf("no record!"); return 1; } count =read_n/(sizeof(struct emp_data)); for(i =0; i < count; i++) { pemp[i].type = PUNCH_ABNORMAL; strcpy(pemp[i].check_in, ""); strcpy(pemp[i].check_out, ""); pemp[i].work_time = 0; } fwrite(buf, 1, read_n, fptr); read_n = fread(buf, 1, 60000, fptr); for(i =0; i < count; i++) { printf("%d ", pemp[i].id); printf("%s ", pemp[i].name); printf("%s ", ret_typestr(pemp[i].type)); printf("%s ", pemp[i].check_in); printf("%s ", pemp[i].check_out); printf("%d\n", pemp[i].work_time); } fclose(fptr); return 0; }
//request_data int request_data(char *fileaddr, char* cmdx) { int count = 0; char buf[60000]; int read_n = 0; int i = 0; struct emp_data *pemp = (struct emp_data *)buf; printf("in request_data()\n"); FILE *fptr; if(!(fptr = fopen(FILE_IN, "r")) ) { printf("in request_data open file[%s] failed!\n", FILE_IN); return 1; } if(!(read_n = fread(buf, 1, 60000, fptr))) { printf("no record!"); return 1; } count =read_n/(sizeof(struct emp_data)); if(strlen(cmdx)==1) { for(i =0; i < count; i++) { printf("%4d ", pemp[i].id); printf("%10s ", pemp[i].name); printf("%-16s ", ret_typestr(pemp[i].type)); printf("%6s ", pemp[i].check_in); printf("%6s ", pemp[i].check_out); printf("%6d\n", pemp[i].work_time); } } else { for(i =0; i < count; i++) { if(pemp[i].id==atoi(cmdx+2)) { printf("%4d ", pemp[i].id); printf("%10s ", pemp[i].name); printf("%-16s ", ret_typestr(pemp[i].type)); printf("%6s ", pemp[i].check_in); printf("%6s ", pemp[i].check_out); printf("%6d\n", pemp[i].work_time); } } } fclose(fptr); return 0; } //check_inout的前半部分 int check_inout(char *fileaddr, char* cmdx) { //取得数量 int count = 0, read_n = 0; int worktime_len = 0; int i = 0; char buf[60000]={0}; int emp_id = atoi(cmdx+2); struct emp_data *pemp = (struct emp_data *)buf; printf("in check_inout() \n"); if(strlen(cmdx)<=2) { p_err(ERR_CMD_INVALID); return 1; } if((atoi(cmdx+2)>1000)||(atoi(cmdx+2)<1)) { p_err(ERR_ID_INVALID); return 1; } //检查时间格式 if((cmdx[17]!=':')||(atoi(cmdx+15)>23)||(atoi(cmdx+15)<0)|| (atoi(cmdx+18)>59)||(atoi(cmdx+18)<0)) { p_err(ERR_TIME_INVALID); return 1; } FILE *fptr; if(!(fptr = fopen(FILE_IN, "r+")) ) { printf("open file[%s] failed!\n", FILE_IN); return 1; } read_n = fread(buf, 1, 60000, fptr); printf("read_n is: %d \n", read_n); count =read_n/(sizeof(struct emp_data)); fclose(fptr); ////check_inout的中间部分 for(i = 0; i < count; i++) { if( (pemp->id)== emp_id) { //更新刷卡记录 //strncpy 后面这个参数6害惨了我! 其实编译的时候会提示一个strncpy的警告! strncpy(pemp->check_out, cmdx+15, 6); //!!!之前的值为5,最后必需写一个'\0',且这个'\0'包含在6中会发生段错误 //printf("-------typecheck----"); pemp->type = type_check(pemp->check_in, pemp->check_out, &worktime_len); pemp->work_time = worktime_len;//worktime(); if(!(fptr = fopen(FILE_IN, "w")) ) { printf("open file[%s] failed!\n", FILE_IN); return 1; } read_n=fwrite(buf,1,count*(sizeof(struct emp_data)),fptr); fclose(fptr); printf("if [0 count]---write bytes :%d\n", read_n); break; } pemp++; } //如果不存在这个人的刷卡记录,包括没有任何记录 if(i == count) { //把结构数据集的指针指向要写入数据的位置 struct emp_data emp_data2; pemp = &emp_data2; pemp->id = emp_id; bzero(pemp->name, 8); strncpy(pemp->name, cmdx+7, 7);//必需拷贝7个字符,最后一个字符置为'\0' pemp->type = PUNCH_ABNORMAL; strncpy(pemp->check_in, cmdx+15, 6); strcpy(pemp->check_out, ""); pemp->work_time = 0; if(!(fptr = fopen(FILE_IN, "a")) ) { printf("open file[%s] failed!\n", FILE_IN); return 1; } read_n=fwrite(pemp,1,sizeof(struct emp_data),fptr); fclose(fptr); printf("if i== count---write bytes :%d,count %d\n", read_n, count); } return 0; } //检查早退迟到等,并可以计算工时,工时通过outlen指针输出 int type_check(char* check_in, char *check_out, int* outlen) { int in_hh, in_mm; int out_hh, out_mm; int hh = 0, mm = 0; int flaglate = 0, flagearly = 0; int flagt =0; printf("in type_check()\n"); if((strlen(check_in)>1)&&(strlen(check_out)>1)) { in_hh = atoi(check_in); in_mm = atoi(check_in+3); out_hh = atoi(check_out); out_mm = atoi(check_out+3); if((in_hh>8)||((in_hh==8)&&(in_mm>0))) { flaglate = 1; flagt = WORK_LATE; } if((out_hh<17)||((out_hh==17)&&(out_mm<30))) { flagearly = 1; flagt = LE***E_EARLY; } if((in_hh>17)||((in_hh==17)&&(in_mm>=30))|| (out_hh<8)||((out_hh==8)&&(out_mm==0))) { printf("----1----abs"); flagt = ABSENT; } if(flaglate&&flagearly) { flagt =LATE_AND_LEARLY; } } else if((strlen(check_in)<1)&&(strlen(check_out)<1)) { printf("----2----abs"); flagt = ABSENT; } else { flagt = PUNCH_ABNORMAL; } //如果,参数outlen== -1 则不计算工时,否则计算 if(*outlen == -1) goto ret; if((flagt == ABSENT)||(flagt == PUNCH_ABNORMAL)) //之前这里flagt == ABSENT少打了一个=号,害得结果又错了 { *outlen = 0; } else { if(in_mm<=out_mm) { *outlen = (out_hh-in_hh)*100 + (out_mm-in_mm); } else { *outlen = (out_hh-in_hh-1)*100 + 60 + (out_mm-in_mm); } } ret: return flagt; } char* ret_typestr(int typecode) { switch(typecode) { case 0: return "NORMAL"; case 1: return "ABSENT"; case 2: return "WORK_LATE"; case 3: return "LE***E_EARLY"; case 4: return "LATE_AND_LEARLY"; case 5: return "PUNCH_ABNORMAL"; default: return "typecode not know!"; } }
相关文章推荐
- 自己早期写的一个简单上下班打卡统计工时的考勤系统【整理版】
- [简单工作流系统的自己搭建]数据库设计-员工打卡、考勤、工资等
- 利用JS跨域做一个简单的页面訪问统计系统
- 一个VB小程序,提醒自己上下班打卡和每小时休息
- C-自己写的一个最简单的班级信息统计程序
- 给自己做的项目添加开机动画,只是一个简单的添加方法,如果系统的方法太麻烦的画,就试试我这个吧,但是如果是想专业一些的话,还是学习系统的吧!!!
- 【自己的整理】node.js直接输出一个非常简单的HTML页面
- 利用JS跨域做一个简单的页面访问统计系统
- 简单定制一个适合自己用的CentOS系统
- TimerTask在遇到修改系统时间不能正常工作,自己写一个简单的TimerTask和Timer
- 自己实现一个简单的网购秒杀系统
- 自己diy的一个简单的家居管理系统
- 【原创】利用Windows系统日志统计员工每天上下班考勤时间
- 利用JS跨域做一个简单的页面访问统计系统
- 自己动手系列——实现一个简单的LinkedLis
- 一个简单检索系统的实现思想
- 不再使用自动编号了。自己写了一个Id生成器,超级简单
- 自己动手做一个迷你Linux 系统
- 详解:Windows系统安装OpenSSL 以及在VC环境下编写一个简单OpenSSL程序
- 一个简单的酒店系统的数据库设计