自己早期写的一个简单上下班打卡统计工时的考勤系统【整理版】
原本这个帖子,是由回复组成的,整个代码分布在各个回复里面,读者不好阅读,现在整个把它们放到正文,方便查看。
这是早期写的一个,仅仅是简单的考勤系统,大致功能是有的,但并未写的很牛叉,采用了文本来记录考勤数据,供小菜一览。
- //头文件: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!";
- }
- }
自己早期写的一个简单上下班打卡统计工时的考勤系统【整理版】相关推荐
- easy-mock写的一个简单的模拟二页的反馈
用easy-mock写的一个简单的模拟二页的反馈,因为后端团队比较传统,所以设计的结构不太规范. 功能:每页10条,共2页,共12条记录,超出参数范围会返错误码: easy模板: {code: fun ...
- AndroidSDK开发6我用kotlin协程写了一个简单sdk
目录 AndroidSDK开发6我用kotlin协程写了一个简单sdk 1.kotlin的依赖和导包如下:(//如果不使用协程可以去掉协程的导包减少sdk包大小) 2.Application代码如下: ...
- 用shell脚本写的一个简单的俄罗斯方块
用shell脚本写的一个简单的俄罗斯方块 代码 代码 测试 下载链接 代码 代码 #!/bin/bash #version 1.2,若非正常退出,请使用附带的killel.sh脚本杀死进程 #定义用于 ...
- 最近写了一个简单的面向对象的脚本语言 Q 语言
最近写了一个简单的面向对象的脚本语言 Q 语言,语法类似于 Javascript, 加入了一些 python 的语法功能. 同时实现了部分的 Javascript prototype 的功能 (个人觉 ...
- 自己写的一个简单的android记事本app
自己写的一个简单的记事本app,效果如下: 一.首先是第一个界面的编写,最上面是一个TextView,中间是一个Linearlayout中嵌套一个listview布局,最下面是一个button.下面附 ...
- 用li写的一个简单的横向导航菜单demo
用ul li写的一个简单的横向导航菜单,很实用: /* 所有class为menu的div中的ul样式 */ div.menu ul { list-style:none; /* 去掉ul前面的符号 */ ...
- 如何复制java卡,使用java做一个简单的集卡程序
使用java做一个简单的集卡程序 本次设想的是要集齐4张卡,每张卡的概率都是25%,如果每个用户集齐需要多少次才能集合完毕 public class Test { public static void ...
- php实现一个简单的访客统计功能
文章来源:https://www.zixuephp.net/article-113.html 对我帮助非常大,谢谢 一.文件方式简单统计 用php实现一个简单的访客统计功能,统计网站的总访问量是多少, ...
- java计算机毕业设计vue开发一个简单音乐播放器源码+mysql数据库+系统+lw文档+部署
java计算机毕业设计vue开发一个简单音乐播放器源码+mysql数据库+系统+lw文档+部署 java计算机毕业设计vue开发一个简单音乐播放器源码+mysql数据库+系统+lw文档+部署 本源码技 ...
最新文章
- 【AWSL】之Linux账号和权限管理(/etc/passwd、/etc/shadow、useradd、passwd、usermod、groupadd、gpasswd...chmod、chown)
- 【深度学习】吴恩达网易公开课练习(class1 week3)
- exchanger_如何通过示例在Java中使用Exchanger
- [Violation] Added non-passive event listener to a scroll-blocking ‘mousewheel‘ event.
- 把Scala代码当作脚本运行
- Node.js从零开发Web Server博客项目笔记
- vue获取输入框得内容_React入坑(四):获取输入框内的内容
- 糖果浏览器和139邮箱巧妙应用:将网页文字一键发送到手机上
- mysql安装忘了root_MySQL - 安装:MySQL忘记root密码的解决办法
- 原生js实现动态生成表格
- 计算机标点符号怎么切换,标点符号转换键是什么?
- mindspore比pytorch快?是的
- 魔兽世界8.0哪个服务器稳定,魔兽世界活得最安逸的BOSS!8.0版本才拿到7.0服务器首杀!...
- 六大设计原则(SOLID)备忘
- MuMu模拟器进行adb操作
- 数据分析统计学基础笔记
- 新东方托福词汇(List 36 ~ List 40)
- 程序员裸辞全职接单一个月的感触
- 【外文翻译】图像中的傅里叶变换
- busybox tools
热门文章
- 影响IPSec的网络问题
- 新一代的数据库SQL审计服务 - SQL洞察
- DELPHI XE3 UPDATE2 出来了
- 谷歌excel表格批量翻译各国语言
- 为什么大部分的股票level2接口都要收费?
- 网上搜集到iOS开发中获取手机IDFA,手机序列号,设备名称,别名,分辨率等信息,这里做个总结
- Pell数列(递归)
- Google Earth Engine(GEE)——MODIS/006/MCD19A2气溶胶数据AOD数据去云去雪分析(北京市为例)
- m227只有一台计算机,惠普m227fdw单面打印如何设置_惠普m227fdw怎么设置单面打印-硬件之家...
- python可以采用交互式的()执行方式,Python语句既可以采用交互式的____执行方式,又可以采用____执行方式。...