您的位置:首页 > 其它

自己早期写的一个简单上下班打卡统计工时的考勤系统【整理版】

2012-06-29 10:58 399 查看
原本这个帖子,是由回复组成的,整个代码分布在各个回复里面,读者不好阅读,现在整个把它们放到正文,方便查看。

这是早期写的一个,仅仅是简单的考勤系统,大致功能是有的,但并未写的很牛叉,采用了文本来记录考勤数据,供小菜一览。





//头文件: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!";
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: