C语言大作业——工资管理系统

需求分析

工资信息存放在文件中,提供文件的输入、输出等操作;要实现浏览功能,提供显示、排序操作;而查询功能要求实现查找操作;另外还应该提供键盘式选择菜单以实现功能选择。

总体设计

整个系统可以分为信息输入、信息添加、信息浏览、信息排序、信息查询和信息统计模块。

详细设计

工资信息采用结构体数组:

Struct Salary_Info
{ 
   int Card_No;                   //工资卡号
   Char name[20];                 //姓名
   int month;                     //月份
   float Init_Salary;               //应发工资 
   float Water_Rate;               //水费
   float Electric_Rate;             //电费
   float tax;                     //税金
   float Final_Salary;             //实发工资
};  
  1. 主函数提供输入、处理和输出部分的函数调用,各功能模块采用菜单方式选择。
  2. 输入模块
    按照工资卡号、姓名、月份、应发工资、水费、电费的顺序输入信息,税金和实发工资根据输入的信息进行计算得到,这些信息被录入到文件中。
    文件操作函数:fopen,fwrite,fclose.
    税金的计算:
    if(应发工资<=800)
    税金=0;
    else if (应发工资>800&&应发工资<=1400)
    税金=(应发工资-800)*5%;
    else if (应发工资>1400)
    税金=(应发工资-1400)*10%;
    实发工资=应发工资-水费-电费-税金。
  3. 添加模块
    增加新的职工工资信息,从键盘输入并逐条写到原来的输入文件中,采用追加而不是覆盖的方式(以”ab”方式打开文件)。
  4. 浏览模块
    分屏显示职工工资信息,可以指定10个1屏,按任意键显示下一屏。通过菜单选择按照工资卡号还是姓名浏览。如果按照卡号浏览,则显示的记录按照卡号升序输出;按照姓名浏览则按照字典序输出(调用排序模块的排序功能)。
  5. 排序模块
    排序模块提供菜单选择,实现按照工资卡号升序、实发工资降序以及姓名字典序排序。排序方法可以选择冒泡排序、插入排序、选择排序等。
  6. 查询模块
    实现按照工资卡号和姓名的查询,采用基本的查找方法即可。
  7. 统计模块
    输入起止月份,按照职工卡号和月份查询记录,把起止月份之间的实发工资金额累加。
    附加:思考在数据输入及添加模块尾部添加排序功能,使得文件中的数据按照卡号排序。这样在查询模块和统计模块可以采用二分查找以提高效率。

ps:代码太长一个代码块放不下,所以每个函数分开了,但他是一个class里的。运行时先新建一个文件,不然没有内容。

#include 
#include 
#include 
#include 
#define N 20

typedef struct Salary_Info
{
    int Card_No;                    //工资卡号
    char name[N];                   //姓名
    int month;                      //月份
    float Init_Salary;              //应发工资
    float Water_Rate;               //水费
    float Electric_Rate;            //电费
    float tax;                      //税金
    float Final_Salary;             //实发工资
} PEO;

//统计信息
typedef struct Salary_Sum
{
    long int Card_No;
    double sum;
    struct Salary_Sum *next;
} SUM;

int people_num;                     //全局变量标记信息条数
int flag = 0;                       //全局变量标记选项

PEO Input(PEO *people);                                     //输入信息
void Output(int num_min,int num_max,PEO *people);           //输出信息
void TaxANDsalay(int min,int max,PEO *people);              //计算税金与实发工资
void Add(int *people_num,PEO *people);                      //添加信息
void Sort(int people_num,PEO *people,int sign);             //信息排序
void Writetofile(int people_num,PEO *people);               //信息存放
void Browse(PEO *people);                                   //打开文件
void Inquire(int people_num,PEO *people);                   //信息查询
void statistics(PEO *people);                               //信息统计
void DeleteMemory(SUM *head);                               //释放内存
PEO Remake(PEO *people);                                    //关闭文件

int main()
{
    int i;
    PEO  people[N];

END1://首页
    printf("——————***工资管理系统***——————\n");
    printf("1--打开文件\n2--新建文件\n3--主菜单\n4--退出系统\n");
    printf("\n请选择执行命令: ");
    scanf("%d",&i);
    while(i<0||i>4)
    {
        printf("数据错误,请重新输入:");
        scanf("%d",&i);
    }
    if(i==1)
    {
        system("cls");
        Remake(people);   
        Browse(people);
    }
    else if(i==2)
    {
        Input(people);
        Writetofile(people_num,people);
    }
    else if(i==3)
    {
        goto END3;
    }
    else if(i==4)
    {
        system("cls");
        printf("——————***谢谢使用***——————\n");
        exit(0);
    }

END2://清屏
    printf("按回车键继续。。。。");
    setbuf(stdin, NULL);            //把输入缓冲区设置为无缓冲,直接从流读取数据
    scanf("%*c");

END3://主菜单
    system("cls");
    printf("————***主菜单***————\n");
    printf("1--信息输入\t2--信息添加\n3--信息浏览\t4--信息排序\n5--信息查询\t6--信息统计\n7--清理缓存\t8--回到首页\n9--退出系统\n");
    printf("\n请选择执行命令: ");
    scanf("%d",&i);
    while(i<0||i>9)
    {
        printf("数据错误,请重新输入:");
        scanf("%d",&i);
    }
    system("cls");
    if(i==1)//信息输入
    {
        printf("——***输入信息***——\n");
        Input(people);
        printf("\n***是否需要保存以上信息到文件?\n0--否\n1--是\n");
        scanf("%d",&flag);
        while(i!=0&&i!=1)
        {
            printf("数据错误,请重新输入:");
            scanf("%d",&flag);
        }
        if(flag==0)
        {
            goto END2;
        }
        else
        {
            Writetofile(people_num,people);
            goto END2;
        }
    }
    else if(i==2)//信息添加
    {
        Add(&people_num,people);
        goto END2;
    }
    else if(i==3)//信息浏览
    {
        printf("***请选择浏览方式***\n1--按卡号浏览\n2--按姓名浏览\n");
        scanf("%d",&flag);
        while(flag!=1&&flag!=2)
        {
            printf("***输入错误,请重新选择:");
            scanf("%d",&flag);
        }
        if(flag==1)
        {
           Sort(people_num,people,1);
        }
        else
        {
            Sort(people_num,people,5);
        }
        Output(0,people_num-1,people);
        goto END2;
    }
    else if(i==4)//信息排序
    {
        Sort(people_num,people,0);
        printf("\n***员工信息表***\n");
        Output(0,people_num-1,people);
        goto END2;
    }
    else if(i==5)//信息查询
    {
        Inquire(people_num,people);
        goto END2;
    }
    else if(i==6)//信息统计
    {
        statistics(people);
        goto END2;
    }
    else if(i==7)//关闭文件
    {
        Remake(people);
        goto END2;
    }
    else if(i==8)//回到首页
    {
        goto END1;
    }
    else if(i==9)//退出系统
    {
        printf("\n——————***谢谢使用***——————\n");
        exit(0);
    }
}

//输入信息
PEO Input(PEO *people)
{
    int i;
    system("cls");
    printf("\n***请输入信息条数:");
    scanf("%d",&people_num);
    while(people_num<=0)
    {
        printf("要添加的信息条数至少为1,请重新输入:");
        scanf("%d",&people_num);
    }

    for(i = 0; i<people_num; i++)
    {
        printf("\n***请输入第%d条信息***\n",i+1);
        printf("\n*工资卡号:");
        scanf("%d",&people[i].Card_No);
        printf("\n*姓名:");
        scanf("%s",people[i].name);
        printf("\n*月份:");
        scanf("%d",&people[i].month);
        while(people[i].month<0||people[i].month>12)
        {
            printf("信息错误,请重新输入:");
            scanf("%d",&people[i].month);
        }
        printf("\n*应发工资:");
        scanf("%f",&people[i].Init_Salary);
        printf("\n*水费:");
        scanf("%f",&people[i].Water_Rate);
        printf("\n*电费:");
        scanf("%f",&people[i].Electric_Rate);
        TaxANDsalay(0,people_num-1,people);
    }
    return *people;
}
//计算税金与实发工资
void TaxANDsalay(int min,int max,PEO *people)
{
    int i;
    for(i=min; i<=max; i++)
    {
        if(people[i].Init_Salary<=800)
            people[i].tax = 0;
        else if(people[i].Init_Salary>800&&people[i].Init_Salary<=1400)
            people[i].tax = (people[i].Init_Salary-800)*0.05;
        else
            people[i].tax = (people[i].Init_Salary-1400)*0.1;
        people[i].Final_Salary = people[i].Init_Salary-people[i].Electric_Rate-people[i].Water_Rate-people[i].tax;

    }

}
//输出信息
void Output(int num_min,int num_max,PEO *people)
{
    int i;
    printf("|     工资卡号   |       姓名      |  月份 |     应发工资    |     水费    |      电费     |     税金    |    实发工资  |\n");
    for(i = num_min; i<=num_max; i++)
    {
        printf("|  %13d | %15s |   %2d  |  %13.2f  |  %8.2f   |   %8.2f    | %10.2f  | %11.2f  |\n",people[i].Card_No,
               people[i].name,
               people[i].month,
               people[i].Init_Salary,
               people[i].Water_Rate,
               people[i].Electric_Rate,
               people[i].tax,
               people[i].Final_Salary
              );
    }
}
//信息存放
void Writetofile(int people_num,PEO *people)
{
    FILE *fp;
    int i;
    char file_name[N];
    char cho;

END:
    printf("***输入文件名(记得加上后缀.txt哦):");
    getchar();
    gets(file_name);
    fp=fopen(file_name, "r");            //检测文件是否已经存在
    if (fp!=NULL)
    {
        fclose(fp);
        do
        {
            printf("文件已存在,是否覆盖?(Y/N)");
            scanf(" %c",&cho);
        }
        while (cho!='y'&&cho!='Y'&&cho!='N'&&cho!='n');
        if (cho=='n'||cho=='N')
        {
            printf("***是否需要重新输入文件名?\n0--否\n1--是\n");
            scanf("%d",&flag);
            if(flag==0)
                return;
            else
            {
                goto END;
            }
        }
    }
    if((fp=fopen(file_name,"w"))==NULL)
    {
        printf("Failure to open %s!\n",file_name);

    }
    fprintf(fp,"|     工资卡号   |       姓名      |  月份 |     应发工资    |     水费    |      电费     |     税金    |    实发工资  |\n");
    for(i = 0; i<people_num; i++)
    {
        fprintf(fp,"|  %13d | %15s |   %2d  |  %13.2f  |  %8.2f   |   %8.2f    | %10.2f  | %11.2f  |\n",people[i].Card_No,
                people[i].name,
                people[i].month,
                people[i].Init_Salary,
                people[i].Water_Rate,
                people[i].Electric_Rate,
                people[i].tax,
                people[i].Final_Salary
               );
    }
    fclose(fp);
}

//信息添加
void Add(int *people_num,PEO *people)
{
    FILE *fp;
    int i;
    int add_num;
    char file_name[N];
    char cho;
    printf("请输入要添加的信息数目:");
    scanf("%d",&add_num);
    while(add_num<1)
    {
        printf("要添加的信息数目至少为1,请重新输入:");
        scanf("%d",&add_num);
    }
    for(i = 0; i<add_num; i++)
    {
        printf("\n***请输入第%d条信息:\n",i+1);
        printf("\n工资卡号:");
        scanf("%d",&people[i+*people_num].Card_No);
        printf("\n姓名:");
        scanf("%s",people[i+*people_num].name);
        printf("\n月份:");
        scanf("%d",&people[i+*people_num].month);
        while(people[i+*people_num].month<1||people[i+*people_num].month>12)
        {
            printf("数据错误,请重新输入:");
            scanf("%d",&people[i+*people_num].month);
        }
        printf("\n应发工资:");
        scanf("%f",&people[i+*people_num].Init_Salary);
        printf("\n水费:");
        scanf("%f",&people[i+*people_num].Water_Rate);
        printf("\n电费:");
        scanf("%f",&people[i+*people_num].Electric_Rate);
        TaxANDsalay(*people_num,i+*people_num,people);
    }
    *people_num += add_num;
    END:printf("***输入文件名:");
    getchar();
    gets(file_name);
    fp=fopen(file_name, "r");            //检测文件是否已经存在
    if (fp==NULL)
    {
        fclose(fp);
        do
        {
            printf("文件不存在,是否要新建文件?(Y/N)");
            scanf(" %c",&cho);
        }
        while (cho!='y'&&cho!='Y'&&cho!='N'&&cho!='n');
        if (cho=='n'||cho=='N')
        {
            printf("***是否需要重新输入文件名?\n0--否\n1--是\n");
            scanf("%d",&flag);
            if(flag==0)
                return;
            else
            {
                goto END;
            }
        }
    }
    if((fp=fopen(file_name,"a"))==NULL)
    {
        printf("Failure to open %s!\n",file_name);
    }
    for(i = 0; i<add_num; i++)
    {
        fprintf(fp,"|  %13d | %15s |   %2d  |  %13.2f  |  %8.2f   |   %8.2f    | %10.2f  | %11.2f  |\n",people[i].Card_No,
                people[i].name,
                people[i].month,
                people[i].Init_Salary,
                people[i].Water_Rate,
                people[i].Electric_Rate,
                people[i].tax,
                people[i].Final_Salary
               );
    }
    fclose(fp);
}
//打开文件
void Browse(PEO *people)
{
    char file_name[N];
    int i=0;
        FILE *fp;
       END: printf("请选择要浏览的文件:\n");
        system("dir");
        scanf("%*c");
        gets(file_name);
        fp = fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件不存在,是否重新输入文件名?\n0--否\n1--是\n");
            scanf("%d",&flag);
            if(flag==0)
            {
                return;
            }
            else
            {
                goto END;
            }
        }
        else
        {
            printf("***文件已存的信息***\n");
            do
            {
                if(i==0)
                {
                    fscanf(fp,"|     工资卡号   |       姓名      |  月份 |     应发工资    |     水费    |      电费     |     税金    |    实发工资  |\n|  %d | %s |   %d  |  %f  |  %f   |   %f    | %f  | %f  |\n",&people[i].Card_No,
                           people[i].name,
                           &people[i].month,
                           &people[i].Init_Salary,
                           &people[i].Water_Rate,
                           &people[i].Electric_Rate,
                           &people[i].tax,
                           &people[i].Final_Salary);
                }
                else
                {
                    fscanf(fp,"|  %d | %s |   %d  |  %f  |  %f   |   %f    | %f  | %f  |\n",
		                    &people[i].Card_No,
		            		 people[i].name,
		                    &people[i].month,
		                    &people[i].Init_Salary,
		                    &people[i].Water_Rate,
		                    &people[i].Electric_Rate,
		                    &people[i].tax,
		                    &people[i].Final_Salary);
                }
                i++;
            }
            while(people[i-1].month>=1&&people[i-1].month<=12);
            people_num=i-1;
            Output(0,people_num-1,people);
        }
        fclose(fp);
}
//信息查询
void Inquire(int people_num,PEO *people)
{
    int i,m=0;
    union Acquire
    {
        int card;
        char name[N];
        int month;
    };
    union Acquire acq;
    printf("***请输入查询的标准:***\n1--工资卡号\n2--姓名\n3--月份\n");
    scanf("%d",&flag);
    if(flag==1)
    {
        printf("***请输入要查询的工资卡号:");
        scanf("%d",&acq.card);
        for(i=0; i<people_num; i++)
        {
            if(people[i].Card_No==acq.card)
            {
                Output(i,i,people);
                m=1;
            }
        }
        if(m==0)
        {
            printf("该卡号不存在!");
        }
    }
    if(flag==2)
    {
        printf("***请输入要查询的员工姓名:");
        getchar();
        gets(acq.name);
        for(i=0; i<people_num; i++)
        {
            if(strcmp(people[i].name,acq.name)==0)
            {
                Output(i,i,people);
                m=1;
            }
        }
        if(m==0)
        {
            printf("该员工不存在!");
        }
    }
    if (flag==3)
    {
        printf("请输入要查询的月份:");
        scanf("%d",&acq.month);
        for(i=0; i<people_num; i++)
        {
            if(people[i].month==acq.month)
            {
                Output(i,i,people);
                m=1;
            }
        }
        if(m==0)
        {
            printf("不存在该月份的信息!");
        }
    }
}
//信息排序
void Sort(int people_num,PEO *people,int sign)
{
    int i,j;
    int x;
    PEO temp;
    if(sign!=1&&sign!=5)
    {
        printf("\n***请选择排序方式:\n");
    printf(" 1--按卡号升序排序\n 2--按卡号降序降序\n 3--按实发工资升序排序\n 4--按实发工资降序排序\n 5--按名字升序\n 6--按名字降序\n");
    scanf("%d",&x) ;
    }
    else
    {
        x=sign;
    }
    if(x==1)
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(people[i].Card_No>people[j].Card_No)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }
    else if(x==2)
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(people[i].Card_No<people[j].Card_No)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }
    else if(x==3)
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(people[i].Final_Salary>people[j].Final_Salary)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }
    else if(x==4)
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(people[i].Final_Salary<people[j].Final_Salary)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }
    else if(x==5)
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(strcmp(people[i].name,people[j].name)>0)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }
    else
    {
        for(i=0; i<people_num; i++)
        {
            for(j = i; j<people_num; j++)
            {
                if(strcmp(people[i].name,people[j].name)<0)
                {
                    temp=people[i];
                    people[i] = people[j];
                    people[j] = temp;
                }
            }
        }
    }

}
//信息统计
void statistics (PEO people[])
{
    int min,max;
    SUM *p = NULL,*q = NULL;
    SUM *head1=NULL;
    int  i=0,j=1,flag1=0;
    printf("请输入月份下限:");
    scanf("%d",&min);
    printf("请输入月份上限:");
    scanf("%d",&max);
    while (i<=people_num)
    {
        if (people[i].month<=max&&people[i].month>=min)         //检测是否符合月份
        {
            if (head1==NULL)                                    //如果新链表头结点为空
            {
                q=(SUM *)malloc(sizeof(SUM));                   //新申请一个结点
                q->next=NULL;                                   //结点的next指向NULL
                q->sum=0;                                       //结点的sum归零
                head1=q;                                        //头指针指向新结点
                q->Card_No=people[i].Card_No;                   //赋值卡号
                q->sum=q->sum+people[i].Final_Salary;           //工资累加
            }
            else
            {
                p=head1;
                while (p!=NULL)
                {
                    if (p->Card_No==people[i].Card_No)
                    {
                        p->sum=p->sum+people[i].Final_Salary;
                        flag1=1;
                        break;
                    }
                    p=p->next;
                }
                if (flag1==0)
                {
                    p=head1;
                    while (p->next!=NULL)
                    {
                        p=p->next;
                    }
                    q=(SUM *)malloc(sizeof(SUM));
                    q->next=NULL;
                    q->sum=0;
                    p->next=q;
                    q->Card_No=people[i].Card_No;
                    q->sum=q->sum+people[i].Final_Salary;
                }
            }
        }
        i++;
        flag1=0;
    }
    p=head1;
    if (head1==NULL)
    {
        printf("未找到符合要求的信息!\n");
        return;
    }
    printf("|  序号 |     工资卡号    |    实发工资    |\n");
    while (p!= NULL)
    {
        printf("| %3d  |  %13ld | %11.2f  |\n", j,p->Card_No,p->sum);
        p = p->next;
        j++;
    }
    DeleteMemory(head1);                                       //释放内存
}
void DeleteMemory(SUM *head)
{
    SUM *p = head, *pr = NULL;
    while (p != NULL)
    {
        pr = p;
        p = p->next;
        free(pr);
    }
}
PEO Remake(PEO *people)
{
    int i;
    for(i = 0; i<people_num; i++)
    {
        people[i].month=-1;
    }
    return *people;
}

还是第一次写这么长的代码,很庆幸它可以跑起来,开心

你可能感兴趣的:(C语言大作业——工资管理系统)