工资系统

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
#define inf 0x3f3f3f
typedef struct {
    char id[50];
    char name[50];
    char gender[50];
    char birth[50];
    double sal;
    double bu;
    double ko;
    double x;
} Employee;

typedef struct date {
    int y;
    int m;
    int d;
}Date;


Employee e[5000];
#define W "test.txt"



int isValidID(char* id);
int isValidName(char* name);
int isValidGender(char* gender);
int isValidDate(char* date);
int isValidSalary(double salary);


void menu();
int ReadFile();
int WriteFile(const Employee tmp);

int count = 0;
void I();
void O();
void T();
void S();
void F();
void D();
void Q();




int main() {
    if (ReadFile() == -1) {
        printf("读取文件失败或文件为空!\n");
    }
    char c;
    while (1) {
        menu();
        scanf("%c", &c);
        switch (c) {
        case 'I': I(); break;
        case 'O': O(); break;
        case 'T': T(); break;
        case 'S': S(); break;
        case 'F': F(); break;
        case 'D': D(); break;
        case 'Q': exit(0);
        default: printf("无效输入,请重新选择。\n"); break;
        }
    }
}

void menu() {
    printf("****************************************\n");
    printf("*   I:输入员工工资信息                 *\n");
    printf("*   O:输出员工工资信息                 *\n");
    printf("*   T:输出员工工资统计信息             *\n");
    printf("*   S:按要求排序后输出员工工资信息     *\n");
    printf("*   F:按员工号查找并输出其工资信息     *\n");
    printf("*   D:按员工号查找并删除其工资信息     *\n");
    printf("*   Q:退出系统                         *\n");
    printf("****************************************\n");
    printf("请选择(I,O,T,S,F,D,Q): ");
}

int ReadFile() {
    FILE* fp = fopen(W, "r");
    if (fp == NULL) {
        return -1;
    }

    char line[256];
    while (fgets(line, sizeof(line), fp)) {
        Employee tmp;
        if (sscanf(line, "%s %s %s %s %lf %lf %lf", tmp.id, tmp.name, tmp.gender, tmp.birth, &tmp.sal, &tmp.bu, &tmp.ko) == 7) {
            tmp.x = tmp.sal + tmp.bu - tmp.ko;
            e[count++] = tmp;
        }
    }

    fclose(fp);
    return 0;
}

int WriteFile(const Employee tmp) {
    FILE* fp = fopen(W, "a");
    if (fp == NULL) {
        return -1;
    }

    fprintf(fp, "%s %s %s %s %.2f %.2f %.2f\n", tmp.id, tmp.name, tmp.gender, tmp.birth, tmp.sal, tmp.bu, tmp.ko);

    fclose(fp);
    return 0;
}

int isValidID(char* id) {
    if (strlen(id) != 4 || !isdigit(id[0]) || id[0] == '0')
    {
        if (strlen(id) != 4)printf("员工号\"%s\"长度必须为:4!\n",id);

        if (id[0] == '0')printf("员工号第1位必须为1--9之间的数字!\n");

        return 0;

    }
    for (int i = 1; i < strlen(id); i++)
    {
        if (!isdigit(id[i]))return 0;
    }

    for (int i = 1; i <= count; i++)
    {
        if (strcmp(id, e[i].id) == 0)
        {
            printf("员工号是员工信息的唯一标识,不允许重复!员工号\"%s\"已经存在。\n", id);
            return 0;//重复
        }
    }
    return 1;
}


int isValidName(char* name) {
    if (strlen(name) >= 4 && strlen(name) <= 8)return 1;
    else return 0;
}


int isValidGender(char* s) {
    if (strcmp(s, "M") == 0 || strcmp(s, "m") == 0 || strcmp(s, "男") == 0)return 1;
    if (strcmp(s, "F") == 0 || strcmp(s, "f") == 0 || strcmp(s, "女") == 0)return 1;
    return 0;
}




int is_leap_year(int year) {
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
        return 1;
    }
    else {
        return 0;
    }
}
int days_in_month(int y,int m)
{
    int days[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    if (is_leap_year(y) && m == 2) return 29;
    else return days[m];
}

int isValidD(const Date d)
{
    if (d.y < 1 || d.y>2024 || d.m < 1 || d.m>12 || d.d > days_in_month(d.y, d.m))return 0;
    return 1;
}

int isValidDate(char* date) {
    Date d;
    int age = 0;
    /*出生日期格式:4位年 - 月 - 日 或 4位年.月.日(长度 <= 10)。
        年龄必须在18~60之间(不考虑男女退休年龄的区别)。*/
    if (!(sscanf(date, "%d-%d-%d", &d.y, &d.m, &d.d) == 3 || sscanf(date, "%d.%d.%d") == 3))return 0;
    if (!isValidD(d))return 0;
    age = 2024 - d.y;
    if (age < 18 || age>60)return 0;
    return 1;
}


int isValidSalary(double salary) {
    return (salary >= 0 && salary <= 99999);
}



int compareByIdAsc(const void* a, const void* b) {
    return strcmp(((Employee*)a)->id, ((Employee*)b)->id);
}

int compareByIdDesc(const void* a, const void* b) {
    return strcmp(((Employee*)b)->id, ((Employee*)a)->id);
}

int compareByName(const void* a, const void* b) {
    return strcmp(((Employee*)a)->name, ((Employee*)b)->name);
}

int compareByGender(const void* a, const void* b) {
    return strcmp(((Employee*)a)->gender, ((Employee*)b)->gender);
}

int compareByAgeAsc(const void* a, const void* b) {
    int ageA = 2024 - atoi(((Employee*)a)->birth);
    int ageB = 2024 - atoi(((Employee*)b)->birth);
    return ageA - ageB;
}

int compareByAgeDesc(const void* a, const void* b) {
    int ageA = 2024 - atoi(((Employee*)a)->birth);
    int ageB = 2024 - atoi(((Employee*)b)->birth);
    return ageB - ageA;
}

int compareBySalaryAsc(const void* a, const void* b) {
    double salaryA = ((Employee*)a)->sal + ((Employee*)a)->bu - ((Employee*)a)->ko;
    double salaryB = ((Employee*)b)->sal + ((Employee*)b)->bu - ((Employee*)b)->ko;
    return (salaryA > salaryB) - (salaryA < salaryB);
}

int compareBySalaryDesc(const void* a, const void* b) {
    double salaryA = ((Employee*)a)->sal + ((Employee*)a)->bu - ((Employee*)a)->ko;
    double salaryB = ((Employee*)b)->sal + ((Employee*)b)->bu - ((Employee*)b)->ko;
    return (salaryB > salaryA) - (salaryB < salaryA);
}


void I() {
    printf("请输入不超过4973名员工的员工信息:\n");
    printf("员工号、姓名、性别、出生日期、岗位工资、补贴总额、代扣总额。\n");
    printf("输入项目之间必须用<空格>分开!\n");
    printf("例如:1010 伍惺委 男 1990-10-20 3220 1500 300 <回车>\n\n");

    printf("要求:\n");
    printf("1、员工号是员工信息的唯一标识,不允许重复,长度 <= 4,格式:第1位为1--9之间的数字,后面的字符可以是任意数字。\n");
    printf("2、姓名必须是2个以上的汉字,最多4个汉字。\n");
    printf("3、性别只能是男(M)或女(F)。\n");
    printf("4、出生日期格式:4位年-月-日 或 4位年.月.日(长度 <= 10)。\n");
    printf("   年龄必须在18~60岁之间。\n");
    printf("5、岗位工资、补贴总额、代扣总额必须在0到99999之间。\n\n");

    printf("如果不想继续输入数据,请按 A <回车> 结束输入。\n");

    while (1) {
        Employee tmp;
        scanf("%s", tmp.id); if (strcmp(tmp.id, "A") == 0) {
            printf("\n");
            break;
        }
        scanf("%s %s %s", tmp.name, tmp.gender, tmp.birth);
        scanf("%lf %lf %lf", &tmp.sal, &tmp.bu, &tmp.ko);
        tmp.x = tmp.sal + tmp.bu - tmp.ko;

        printf("\n");
        if (!isValidID(tmp.id))
        {
            printf("刚输入的员工数据有错,数据没有被保存!\n");
            continue;
        }
        if (!isValidName(tmp.name))
        {
            printf("刚输入的员工数据有错,数据没有被保存!\n");
            continue;
        }
        if (!isValidGender(tmp.gender))
        {
            printf("性别只能是\"男(M)\"或\"女(F)\"!\n");
            printf("刚输入的员工数据有错,数据没有被保存!\n");
            printf("\n");
            continue;
        }
        if (!isValidDate(tmp.birth))
        {
            printf("出生日期\"%s\"长度必须<=10!格式:4位年-月-日 或 4位年.月.日\n", tmp.birth);
            printf("刚输入的员工数据有错,数据没有被保存!\n");
            printf("\n");
            continue;
        }
        if (!isValidSalary(tmp.x))
        {
            printf("刚输入的员工数据有错,数据没有被保存!\n");
            continue;
        }
        printf("\n");

        WriteFile(tmp);
        e[++count] = tmp;
    }
    printf("员工信息已保存。\n\n");

    getchar();
}

void O() {
    if (count == 0) {
        printf("没有员工信息。\n");
        return;
    }
    printf("\n");
    printf("现有员工总数为:%d\n\n", count);
    printf("员工号   姓名    性别    出生日期  岗位工资  补贴总额  代扣总额  应发工资\n");
    printf("========================================================================\n");
    for (int i = 0; i < count; i++) {
        printf("%4s   %6s   %4s   %-12s   %6.2f   %6.2f   %6.2f   %6.2f\n",
            e[i].id, e[i].name, e[i].gender, e[i].birth, e[i].sal, e[i].bu, e[i].ko,e[i].x);
    }
    printf("========================================================================\n");
    printf("\n");
    getchar();
}


int Man(const char *s) {  
    printf("%s", s);  
    //if (s == "M" || s == "m" || s == "男")return 1;
    if (strcmp(s, "M") == 0 || strcmp(s, "m") == 0 || strcmp(s, "男") == 0)return 1;
    else return 0;
}


void T() {
    if (count == 0) {
        printf("没有员工信息。\n");
        return;
    }

    double totalSalary = 0;
    double totalBonus = 0;
    double totalDeduction = 0;
    double totalNetSalary = 0;
    int ManCount = 0;
    int WomanCount = 0;
    double totalMan = 0;
    double totalWoman = 0;
    double maxSalary = -inf;
    double minSalary = inf;

    for (int i = 0; i < count; i++) {
        totalSalary += e[i].sal;
        totalBonus += e[i].bu;
        totalDeduction += e[i].ko;
        double tmp =e[i].x;
        totalNetSalary += tmp;

        if (maxSalary < tmp)maxSalary = tmp;
        if (minSalary > tmp)minSalary = tmp;

        if (Man(e[i].gender)==1)
        {
            ManCount++;
            totalMan += tmp;
        }
        else
        {
            WomanCount++;
            totalWoman += tmp;
        }
            
    }

    printf("\n员工工资统计信息:\n");
    printf("====================================\n");
    printf("应发工资最高为:%.2f, 最低为:%.2f, 所有员工应发工资总额为:%.2f\n\n", maxSalary,minSalary, totalNetSalary);
    printf("男性员工人数为:%d,女性员工人数为:%d\n\n", ManCount, WomanCount);
    //printf("总岗位工资: %.2f\n", totalSalary);
   // printf("总补贴总额: %.2f\n", totalBonus);
   // printf("总代扣总额: %.2f\n", totalDeduction);
   // printf("总应发工资: %.2f\n", totalNetSalary);
    //printf("平均岗位工资: %.2f\n", totalSalary / count);
    //printf("平均补贴总额: %.2f\n", totalBonus / count);
  //  printf("平均代扣总额: %.2f\n", totalDeduction / count);
    printf("平均应发工资: %.2f(其中:男性平均值为:%.2f,女性平均值为:%.2f)\n", totalNetSalary / count,totalMan/ManCount,totalWoman/WomanCount);
    printf("====================================\n");

    getchar();
}


void S() {
    if (count == 0) {
        printf("没有员工信息。\n");
        return;
    }

    printf("\n排序方式选择菜单\n");
    printf("================================\n");
    printf("1:按员工号从小到大排序\n");
    printf("2:按员工号从大到小排序\n");
    printf("3:按员工姓名排序\n");
    printf("4:按员工性别排序\n");
    printf("5:按员工年龄从小到大排序\n");
    printf("6:按员工年龄从大到小排序\n");
    printf("7:按员工应发工资从小到大排序\n");
    printf("8:按员工应发工资从大到小排序\n");
    printf("q:不排序退出\n");
    printf("================================\n");
    printf("请选择(1--8和q):");

    char choice;
    scanf(" %c", &choice);  // 用空格跳过缓冲区中的换行符

    switch (choice) {
    case '1':
        qsort(e, count, sizeof(Employee), compareByIdAsc);
        break;
    case '2':
        qsort(e, count, sizeof(Employee), compareByIdDesc);
        break;
    case '3':
        qsort(e, count, sizeof(Employee), compareByName);
        break;
    case '4':
        qsort(e, count, sizeof(Employee), compareByGender);
        break;
    case '5':
        qsort(e, count, sizeof(Employee), compareByAgeAsc);
        break;
    case '6':
        qsort(e, count, sizeof(Employee), compareByAgeDesc);
        break;
    case '7':
        qsort(e, count, sizeof(Employee), compareBySalaryAsc);
        break;
    case '8':
        qsort(e, count, sizeof(Employee), compareBySalaryDesc);
        break;
    case 'q':
        return;
    default:
        printf("无效选择,请重新选择。\n");
        return;
    }

    printf("\n排序后的员工信息:\n");
    printf("员工号   姓名    性别    出生日期     岗位工资  补贴总额  代扣总额  应发工资\n");
    printf("========================================================================\n");
    for (int i = 0; i < count; i++) {
        printf("%4s   %6s   %4s   %-12s   %6.2f   %6.2f   %6.2f   %6.2f\n",
            e[i].id, e[i].name, e[i].gender, e[i].birth, e[i].sal, e[i].bu, e[i].ko, e[i].x);
    }
    printf("========================================================================\n");

    getchar();
}


void F() {
    if (count == 0) {
        printf("没有员工信息。\n");
        return;
    }

    char id[50];
    printf("请输入待查询的员工号:");
    scanf("%s", id);

    for (int i = 0; i < count; i++) {
        if (strcmp(e[i].id, id) == 0) {
            printf("\n");
            printf("员工号   姓名    性别    出生日期     岗位工资  补贴总额  代扣总额  应发工资\n");
            printf("%4s   %6s   %4s   %-12s   %6.2f   %6.2f   %6.2f   %6.2f\n",
                e[i].id, e[i].name, e[i].gender, e[i].birth, e[i].sal, e[i].bu, e[i].ko, e[i].sal + e[i].bu - e[i].ko);
            printf("\n");
            getchar();
            return;
        }
    }
    printf("\n");
    printf("没有找到该员工。\n");
    printf("\n");
    getchar();
}

void D() {
    if (count == 0) {
        printf("没有员工信息。\n");
        return;
    }

    char id[50];
    printf("请输入待删除的员工号:");
    scanf("%s", id);

    for (int i = 0; i < count; i++) {
        if (strcmp(e[i].id, id) == 0) {
            for (int j = i; j < count - 1; j++) {
                e[j] = e[j + 1];  
            }
            count--; 
            printf("员工 [%s] 的信息已删除!\n", id);
            getchar();
            return;
        }
    }
    printf("\n");
    printf("没有找到该员工。\n");
    printf("\n");
    getchar();
}


posted @ 2024-11-30 19:06  某朝  阅读(4)  评论(0编辑  收藏  举报