教职工工资管理系统
系统要求:
每名教职工的信息包括:教工号、姓名、性别、学历、电话、基本工资、津贴、生活补贴、应发工资、电话费、水电费、所得税、公积金、合计扣款、实发工资。
注:应发工资=基本工资+津贴+生活补贴;合计扣款=电话费+水电费+所得税+公积金;实发工资=应发工资 一合计扣款。设计一个教师工资管理系统,使之能提供以下功能:
(1)录入教职工信息,能连续录入多名教职工的信息,并按教工号以小到大的顺序存入文件,要求数据录入时有一定的容错能力,比如输入的教工号小于0,就提示不合法,要求重新输入;且教工的实发工资、应发工资、合计扣款由程序根据计算规则自动计算;
(2)删除(修改)教工信息,输入将删除或修改的教工号,读出该教师信息,并要求对此进行确认,
以决定是否删除或修改,将删除或修改后的信息写到文件中,一次删除(修改)一条信息;
(3)按教工号插入新教工的信息,当录入了重复的姓名和教工号时,则提示数据录入重复并取消录
入;
(4)浏览教工信息,显示所有教工的信息:
(5)教工数据查询,能实现按教工号查询和按电话号码查询,即输入教工号或电话号码,即读出所
有数据信息,并显示出来。
(6)用菜单进行管理;
(7)只有正确输入用户名密码才能使用此系统;
(8)系统数据以动态链表存储,对系统的增删改查等操作都是利用链表来实现。数据信息以二进制形式存储,程序退出时提示保存数据,进入系统时提示从文件读入上次保存数据。数据个数不得少于10个。
(9)宏、数据结构以及函数原型等放在头文件中,并使用条件编译。
代码如下
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<dos.h> //清屏函数调用
#include <windows.h> //延迟函数调用
// 定义宏
#define FILENAME "data.dat" // 数据文件名
//定义结构体 储存老师信息
typedef struct Teacher {
int id; //教工号
char name[20]; // 姓名
char gender[10]; // 性别
char education[20]; // 学历
char phone[20]; // 电话
float base_salary; // 基本工资
float allowance; // 津贴
float living_subsidy; // 生活补贴
float gross_salary; // 应发工资
float telephone_fee; // 电话费
float utilities_fee; // 水电费
float income_tax; // 所得税
float provident_fund; // 公积金
float deduction_total; // 合计扣款
float net_salary; // 实发工资
struct Teacher *next; // 下一个节点
} Teacher;
Teacher *head = NULL;
// 定义各个功能函数
void login(); //登录
void display_menu(); // 显示菜单
void mainmenu(); //main函数主体
Teacher *load_data(); //加载数据
Teacher *insert_teacher(Teacher *head, Teacher *teacher); //插入教师信息
Teacher *create_teacher(); // 创建教师信息
Teacher *find_teacher_by_id(Teacher *head, int id); // 按教工号查找教师
Teacher *find_teacher_by_phone(Teacher *head, char *phone); // 按电话号码查找教师
Teacher *delete_teacher(Teacher *head, int id); // 删除教师信息
Teacher *update_teacher(Teacher *head, int id); // 修改教师信息
void save_data(Teacher *head); // 保存数据
void print_teacher(Teacher *teacher); // 打印教师信息
void print_teacher_xg(Teacher *teacher); // 打印教师信息(修改)
void print_all_teachers(Teacher *head); // 打印所有教师信息
void display_menu() /*菜单函数*/
{
printf(" ******************菜单管理**************************************\n");
printf(" * 1.录入教师信息 *\n");
printf(" * 2.删除教师信息 *\n");
printf(" * 3.插入教师信息 *\n");
printf(" * 4.浏览教师信息 *\n");
printf(" * 5.查询教师信息 *\n");
printf(" * 6.修改教师信息 *\n");
printf(" * 7.退出程序 *\n");
printf(" *************教职工工资管理系统*********************************\n");
printf("\n");
printf("\n");
}
void mainmenu(){
int i;
display_menu();
int choice;
printf("\n请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1: { // 录入教师信息
int n;
printf("请输入教职工个数:\n");
scanf("%d",&n);
for(int i=1;i<=n;i++){
Teacher *teacher = create_teacher();
head = insert_teacher(head, teacher);
}
break;
}
case 2: { // 删除教师信息
int id;
printf("请输入要删除的教师的教工号:");
scanf("%d", &id);
head = delete_teacher(head, id);
break;
}
case 3: { // 插入教师信息
Teacher *teacher = create_teacher();
head = insert_teacher(head, teacher);
break;
}
case 4: { // 浏览教师信息
print_all_teachers(head);
break;
}
case 5: { // 查询教师信息
int choice2;
printf("请选择查询方式(1.按教工号查询,2.按电话号码查询):");
scanf("%d", &choice2);
switch (choice2) {
case 1: { // 按教工号查询
int id;
printf("请输入要查询的教师的教工号:");
scanf("%d", &id);
Teacher *teacher = find_teacher_by_id(head, id);
if (teacher != NULL) {
print_teacher(teacher);
} else {
printf("没有找到该教师。\n");
}
break;
}
case 2: { // 按电话号码查询
char phone[20];
printf("请输入要查询的教师的电话号码:");
scanf("%s", phone);
Teacher *teacher = find_teacher_by_phone(head, phone);
if (teacher != NULL) {
print_teacher(teacher);
} else {
printf("没有找到该教师。\n");
}
break;
}
default:
printf("输入有误,请重新选择操作。\n");
break;
}
break;
}
case 6: { //修改教师信息
int id;
printf("请输入教师教工号:\n");
scanf("%d",&id);
head = update_teacher(head,id);
break;
}
case 7: { // 退出程序
save_data(head); // 保存数据
printf("谢谢使用,再见!\n");
exit(0);
}
default:
printf("输入有误,请重新选择操作。\n");
Sleep(200);
system("cls");
break;
}
printf("是否继续进行:1、继续进行 2、停止\n");
scanf("%d",&i);
switch(i){
case 1:{
system("cls");
mainmenu();
break;
}
case 2:{
printf("谢谢使用,再见!\n");
exit(0);
}
default:{
printf("输入有误,请重新选择操作。\n");
Sleep(200);
system("cls");
break;
}
}
}
int main() {
login(); // 登录
Teacher *head = load_data(); // 加载数据
while (1) { //循环
mainmenu();
}
}
// 登录
void login() {
int flag = 0, i = 0 ;
char username[20], password[20];
char z_user[20] = "123456",z_pass[20] = "123456";
printf("请输入用户名:");
scanf("%s", username);
printf("请输入密码:");
scanf("%s", password);
//账号密码判断
if((strcmp(z_user,username))||(strcmp(z_pass,password))){ //匹配错误,重新输入
printf("请输入正确的用户名和密码\n");
Sleep(500);
system("cls");
login();
}else flag = 1;
if(flag == 1){
printf("用户名密码正确\n");
Sleep(200);
printf("正在进入系统\n");
Sleep(200);
system("cls");
}
}
/*
// 加载数据
Teacher *load_data() {
int i=0;
FILE *fp = fopen(FILENAME, "rb");
if (fp == NULL) {
return NULL;
}
Teacher *head = NULL;
//Teacher *teacher = (Teacher *) malloc(sizeof(Teacher));
while (fread(teacher,sizeof(Teacher),1,fp)==1) {
Teacher *teacher = (Teacher *) malloc(sizeof(Teacher));
/*
Teacher *teacher = (Teacher *) malloc(sizeof(Teacher));
int read_count = fread(teacher, sizeof(Teacher), 1, fp);
printf("\n1.教工号:%d,\t2.姓名:%s,\t3.性别:%s,\t4.学历:%s,\n5.电话:%s,\t6.基本工资:%.2f,\t7.津贴:%.2f,\t8.生活补贴:%.2f,\n9.应发工资:%.2f,\t10.电话费:%.2f,\t11.水电费:%.2f,\t12.所得税:%.2f,\n13.公积金:%.2f,\t14.合计扣款:%.2f,\t15.实发工资:%.2f\n",
teacher->id, teacher->name, teacher->gender, teacher->education, teacher->phone, teacher->base_salary,
teacher->allowance, teacher->living_subsidy, teacher->gross_salary, teacher->telephone_fee,
teacher->utilities_fee, teacher->income_tax, teacher->provident_fund, teacher->deduction_total,
teacher->net_salary);
if (read_count == 0) {
//free(teacher);
break;
}
head = insert_teacher(head, teacher);
i++;
free(teacher);
}
printf("现有文件中含有教师信息个数为:\n");
printf("%d\n",i);
fclose(fp);
return head;
}
*/
// 加载数据
Teacher *load_data() {
int i=0;
FILE *fp = fopen(FILENAME, "rb");
if (fp == NULL) {
return NULL;
}
Teacher *head = NULL;
while (1) {
Teacher *teacher = (Teacher *) malloc(sizeof(Teacher));
int read_count = fread(teacher, sizeof(Teacher), 1, fp);
/*
printf("\n1.教工号:%d,\t2.姓名:%s,\t3.性别:%s,\t4.学历:%s,\n5.电话:%s,\t6.基本工资:%.2f,\t7.津贴:%.2f,\t8.生活补贴:%.2f,\n9.应发工资:%.2f,\t10.电话费:%.2f,\t11.水电费:%.2f,\t12.所得税:%.2f,\n13.公积金:%.2f,\t14.合计扣款:%.2f,\t15.实发工资:%.2f\n",
teacher->id, teacher->name, teacher->gender, teacher->education, teacher->phone, teacher->base_salary,
teacher->allowance, teacher->living_subsidy, teacher->gross_salary, teacher->telephone_fee,
teacher->utilities_fee, teacher->income_tax, teacher->provident_fund, teacher->deduction_total,
teacher->net_salary);
*/
if (read_count == 0) {
free(teacher);
break;
}
head = insert_teacher(head, teacher);
i++;
}
printf("现有文件中含有教师信息个数为:\n");
printf("%d\n",i);
fclose(fp);
return head;
}
// 保存数据
void save_data(Teacher *head) {
FILE *fp = fopen(FILENAME, "wb+"); //以写的方式打开文件
if (fp == NULL) {
printf("无法打开文件。\n");
return;
}
Teacher *p = head;
while (p != NULL) {
fwrite(p, sizeof(Teacher), 1, fp);
p = p->next;
}
fclose(fp);
}
// 插入教师信息
Teacher *insert_teacher(Teacher *head, Teacher *teacher) {
if (head == NULL) { // 如果链表为空,直接插入
teacher->next = NULL;
return teacher;
}
if (teacher->id < head->id) { // 如果教工号比头节点小,插入到头部
teacher->next = head;
return teacher;
}
Teacher *p = head;
while (p->next != NULL && p->next->id < teacher->id) {
p = p->next;
}
if (p->next == NULL) { // 如果已经到达尾部,插入到尾部
p->next = teacher;
teacher->next = NULL;
} else { // 否则插入到中间
teacher->next = p->next;
p->next = teacher;
}
return head;
}
// 创建教师信息
Teacher *create_teacher() {
Teacher *teacher = (Teacher *) malloc(sizeof(Teacher));
Teacher *p = head;
printf("请输入教工号:");
scanf("%d", &teacher->id);
if(teacher->id < 0){
printf("\n输入id错误\n");
printf("请输入正确id\n");
Sleep(500);
system("cls");
mainmenu();
}
while(p != NULL){
if(teacher->id == p->id){
printf("\n输入错误!");
printf("\n输入教职工工号重复!\n");
Sleep(500);
system("cls");
free(teacher);
mainmenu();
}
p = p->next;
}
p = head;
printf("请输入姓名:");
scanf("%s", teacher->name);
while(p != NULL){
if(strcmp(teacher->name,p->name) == 0){
printf("\n输入错误!");
printf("\n输入教职工姓名重复!\n");
Sleep(500);
system("cls");
free(teacher);
mainmenu();
}
p = p->next;
}
printf("请输入性别:");
scanf("%s", teacher->gender);
printf("请输入学历:");
scanf("%s", teacher->education);
printf("请输入电话:");
scanf("%s", teacher->phone);
printf("请输入基本工资:");
scanf("%f", &teacher->base_salary);
printf("请输入津贴:");
scanf("%f", &teacher->allowance);
printf("请输入生活补贴:");
scanf("%f", &teacher->living_subsidy);
printf("请输入电话费:");
scanf("%f", &teacher->telephone_fee);
printf("请输入水电费:");
scanf("%f", &teacher->utilities_fee);
printf("请输入所得税:");
scanf("%f", &teacher->income_tax);
printf("请输入公积金:");
scanf("%f", &teacher->provident_fund);
//计算各个数据
teacher->gross_salary = teacher->base_salary + teacher->allowance + teacher->living_subsidy;
teacher->deduction_total = teacher->telephone_fee + teacher->utilities_fee + teacher->income_tax + teacher->provident_fund;
teacher->net_salary = teacher->gross_salary - teacher->deduction_total;
teacher->next = NULL;
printf("\n");
printf("\n工号为 %d 的教师信息",teacher->id);
printf("\n输入完成!\n");
Sleep(500);
return teacher;
}
// 打印教师信息
void print_teacher(Teacher *teacher) {
printf("\n");
printf("教工号:%d,\t姓名:%s,\t性别:%s,\t学历:%s,\n电话:%s,\t基本工资:%.2f,\t津贴:%.2f,\t生活补贴:%.2f,\n应发工资:%.2f,\t电话费:%.2f,\t水电费:%.2f,\t所得税:%.2f,\n公积金:%.2f,\t合计扣款:%.2f,\t实发工资:%.2f\n",
teacher->id, teacher->name, teacher->gender, teacher->education, teacher->phone, teacher->base_salary,
teacher->allowance, teacher->living_subsidy, teacher->gross_salary, teacher->telephone_fee,
teacher->utilities_fee, teacher->income_tax, teacher->provident_fund, teacher->deduction_total,
teacher->net_salary);
printf("\n");
}
// 打印教师信息(修改)
void print_teacher_xg(Teacher *teacher) {
system("cls");
printf("\n1.教工号:%d,\t2.姓名:%s,\t3.性别:%s,\t4.学历:%s,\n5.电话:%s,\t6.基本工资:%.2f,\t7.津贴:%.2f,\t8.生活补贴:%.2f,\n9.应发工资:%.2f,\t10.电话费:%.2f,\t11.水电费:%.2f,\t12.所得税:%.2f,\n13.公积金:%.2f,\t14.合计扣款:%.2f,\t15.实发工资:%.2f\n",
teacher->id, teacher->name, teacher->gender, teacher->education, teacher->phone, teacher->base_salary,
teacher->allowance, teacher->living_subsidy, teacher->gross_salary, teacher->telephone_fee,
teacher->utilities_fee, teacher->income_tax, teacher->provident_fund, teacher->deduction_total,
teacher->net_salary);
printf("\n");
}
// 打印所有教师信息
void print_all_teachers(Teacher *head) {
if (head == NULL) {
printf("没有任何教师信息。\n");
return;
}
Teacher *p = head;
while (p != NULL) {
print_teacher(p);
p = p->next;
}
}
// 按教工号查找教师
Teacher *find_teacher_by_id(Teacher *head, int id) {
Teacher *p = head;
while (p != NULL) {
if (p->id == id) {
return p;
}
p = p->next;
}
return NULL;
}
// 按电话号码查找教师
Teacher *find_teacher_by_phone(Teacher *head, char *phone) {
Teacher *p = head;
while (p != NULL) {
if (strcmp(p->phone, phone) == 0) {
return p;
}
p = p->next;
}
return NULL;
}
// 删除教师信息
Teacher *delete_teacher(Teacher *head, int id) {
if (head == NULL) {
printf("没有任何教师信息。\n");
return NULL;
}
if (head->id == id) { // 如果要删除的是头节点
Teacher *temp = head;
head = head->next;
free(temp);
printf("删除成功。\n");
return head;
}
Teacher *p = head;
while (p->next != NULL && p->next->id != id) {
p = p->next;
}
if (p->next == NULL) {
printf("没有找到要删除的教师。\n");
} else {
Teacher *temp = p->next;
p->next = temp->next;
free(temp);
printf("删除成功。\n");
}
Sleep(200);
system("cls");
return head;
}
// 修改教师信息
Teacher *update_teacher(Teacher *head, int id) {
int a; //选择修改内容
int flag = 0; //定义标志
int flag_1 = 0; //选择标志
int flag_2 = 0; //选自标志
int id_1; //教工号
char name_1[20]; // 姓名
char gender_1[10]; // 性别
char education_1[20]; // 学历
char phone_1[20]; // 电话
float base_salary_1; // 基本工资
float allowance_1; // 津贴
float living_subsidy_1; // 生活补贴
float gross_salary_1; // 应发工资
float telephone_fee_1; // 电话费
float utilities_fee_1; // 水电费
float income_tax_1; // 所得税
float provident_fund_1; // 公积金
float deduction_total_1; // 合计扣款
float net_salary_1; // 实发工资
Teacher *teacher = find_teacher_by_id(head, id);
if (teacher == NULL) {
printf("没有找到要修改的教师。\n");
return NULL;
}
else{
print_teacher_xg(teacher);
printf("请选择要修改的内容:\n");
scanf("%d",&a);
switch(a){
case 1:{
printf("教工号改为:\n");
scanf("%d",&id_1);
if(id_1 < 0){
//flag_1 = 1;
printf("修改失败\n");
printf("\n教职工工号不能小于零!\n");
break;
}
teacher->id = id_1;
flag = 1;
flag_2 = 1;
break;
}
case 2:{
printf("姓名改为:\n");
scanf("%s",&teacher->name);
flag = 1;
break;
}
case 3 :{printf("性别改为:\n");
scanf("%s",&teacher->gender);
flag = 1;
break;
}
case 4 :{
printf("学历改为:\n");
scanf("%s",&teacher->education);
flag = 1;
break;
}
case 5 :{
printf("电话改为:\n");
scanf("%s",&teacher->phone);
flag = 1;
break;
}
case 6 :{
printf("基本工资改为:\n");
scanf("%f",&base_salary_1);
teacher->base_salary = base_salary_1;
flag = 1;
break;
}
case 7 :{
printf("津贴改为:\n");
scanf("%f",&allowance_1);
teacher->allowance = allowance_1;
flag = 1;
break;
}
case 8:{
printf("生活补贴改为:\n");
scanf("%f",&living_subsidy_1);
teacher->living_subsidy = living_subsidy_1;
flag = 1;
break;
}
case 9:{
printf("应发工资改为:\n");
scanf("%f",&gross_salary_1);
teacher->gross_salary = gross_salary_1;
flag = 1;
break;
}
case 10 :{
printf("电话费改为:\n");
scanf("%f",&telephone_fee_1);
teacher->telephone_fee = telephone_fee_1;
flag = 1;
break;
}
case 11 :{
printf("水电费改为:\n");
scanf("%f",&utilities_fee_1);
teacher->utilities_fee = utilities_fee_1;
flag = 1;
break;
}
case 12 :{
printf("所得税改为:\n");
scanf("%f",&income_tax_1);
teacher->income_tax = income_tax_1;
flag = 1;
break;
}
case 13 :{
printf("公积金改为:\n");
scanf("%f",&provident_fund_1);
teacher->provident_fund = provident_fund_1;
flag = 1;
break;
}
case 14 :{
printf("合计扣款改为:\n");
scanf("%f",&deduction_total_1);
teacher->deduction_total = deduction_total_1;
flag = 1;
break;
}
case 15 :{
printf("实发工资改为:\n");
scanf("%f",&net_salary_1);
teacher->net_salary = net_salary_1;
flag = 1;
break;
}
default :printf("\n输入错误,请重新输入!\n");
break;
}
printf("\n");
/*
if(flag_2 == 1){
head = insert_teacher(head, teacher);
}
*/
if(flag == 1){
printf("\n是否确定更改所修改的信息?\n是请按1;不是请按2;\n");
scanf("%d",&flag_1);
}
printf("\n浏览修改后的教职工信息:\n");
print_teacher(teacher);
/*
printf("\n继续修改按1,停止修改按0\n");
scanf("%d,&flag_2");
switch(flag_2){
case 1:{
head = update_teacher(head,id);
break;
}
case 0:break;
default : break;
}
*/
}
printf("\n");
return head;
}
代码只为本人日常学习使用,如有代码问题,欢迎各位大佬指出。