原本这个帖子,是由回复组成的,整个代码分布在各个回复里面,读者不好阅读,现在整个把它们放到正文,方便查看。
这是早期写的一个,仅仅是简单的考勤系统,大致功能是有的,但并未写的很牛叉,采用了文本来记录考勤数据,供小菜一览。
- //头文件: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,
- LEAVE_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 = LEAVE_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 "LEAVE_EARLY";
- case 4: return "LATE_AND_LEARLY";
- case 5: return "PUNCH_ABNORMAL";
- default: return "typecode not know!";
- }
- }