5.1小长假,准备写点啥,然后一天写完,改了两天,终于搞完了
写了一个员工管理系统,一半参考老师代码,一般自己敲的。先给个基本框架。
基本架构搞完,现在直接上code
第一个要给大家的是头文件,需要将需要用到的函数再头文件中声明,还有需要用到的结构还有会用到的一些常用的输出形式再头中定义成宏,但是那,定义成宏之后最好就不要再改了,不然你就嗝屁。
#ifndef _EMP_H_
#include
#include
#include
#include
#include
#include
#define SIZE 15
#define MAX_SIZE 10
#define T_MAX 12
#define MAX_ADDR_SIZE 20
#define WRITEFORMAT "%s%s%s%s%d%s%d%s%s%s"
#define READFORMAT "%s\n%s\n%s\n%s\n%d\n%s\n%d\n%s\n%s\n%s\n"
#define WRITEDATE emp->Num,emp->Name,emp->Duty,emp->Sex,&(emp->Age),emp->Edu,&(emp->Tel_offer),emp->Tel,emp->QQ,emp->Addr
#define READDATE emp->Num,emp->Name,emp->Duty,emp->Sex,emp->Age,emp->Edu,emp->Tel_offer,emp->Tel,emp->QQ,emp->Addr
char password[MAX_SIZE];
char gfirst, gsave;
//定义员工私人信息,包括工号,姓名,职称,性别,年龄,文化程度,工资,私人电话, QQ号码,住址等10项内容
typedef enum{
QUIT,
ADD,
FIND,
DEL,
SHOW,
MOD,
SUM,
RESET
};
typedef struct Person
{
char Num[SIZE]; //工号
char Name[SIZE]; //姓名
char Duty[MAX_SIZE]; //职称址
char Sex[3]; //性别
short Age; //年龄
char Edu[MAX_SIZE]; //文化程度
int Tel_offer; //工资
char Tel[T_MAX]; //私人电话
char QQ[T_MAX]; //QQ号码
char Addr[MAX_ADDR_SIZE]; //住址
struct Person *next;
}Person;
Person *emp_first; //定义头指针
Person *emp_end; //定义尾指针
//定义查找函数(按姓名查找,工号查找,电话查找,按QQ查找)
Person* FindByName(Person *emp);
Person* FindByNum(Person *emp);
Person* FindByTel(Person *emp);
Person* FindByQQ(Person *emp);
//定义功能函数包括(添加,查找,删除,显示,修改员工信息,统计,修改密码)7个部分
void AddPerson();
void FindPerson();
void DelPerson();
void ShowPerson();
void ModifyPerson();
void SummaryPerson();
void ResetPsw();
//定义初始化函数
void Checkfirst();
void Login();
void Menu();
//对数据的操作
void ReadDate();
void SaveDate();
#endif
接下来给大家的是主函数,用函数表来替换你的SWITCH函数,使主函数变得简单,
#include"emp.h"
void(*fun_table[])() = { NULL, AddPerson, FindPerson, DelPerson, ShowPerson, ModifyPerson, SummaryPerson, ResetPsw };
int main(int argc, char *argv[])
{
gfirst = gsave = 0; //初次登录时,将其设置为0,
emp_first = emp_end = NULL; //将头尾指针指空,等待从文件读入数据
Checkfirst(); //检查初次登录
Login(); //密码检测,也就是登录检查
ReadDate(); //从文本文件中读取数据
int choice = 1;
system("cls");
while (choice)
{
Menu();
printf("请输入你的选择>");
scanf("%d", &choice);
if (choice == QUIT)
break;
else if (choice < 0 || choice >7)
{
printf("输入错误,请重新选择.....\n");
system("pause");
system("cls");
continue;
}
else
fun_table[choice]();
getchar();
system("cls");
}
printf("欢迎使用,再见\n");
system("pause");
return 0;
}
接下来要给大家的时登录前的检测函数,包括初次登录检测和密码检测
#include"emp.h"
#include
//检查是否为初次登录
void Checkfirst()
{
FILE *fp = fopen("config.txt", "r");
FILE *fp1;
char pwd[MAX_SIZE], pwd1[MAX_SIZE];
int i, j;
if (fp == NULL) //第一次进入该系统
{
printf("\n\t新系统还未进行初始化,请您按任意键继续进行操作。\n");
system("pause");
printf("----------------------------------------------------------------\n");
while (1)
{
printf("\n\t请设置登陆密码(最多9位):");
for (i = 0; i < 9 && ((pwd[i] = _getch()) != 13); ++i) //输入密码回车表示结束
printf("*");
pwd[i] = '\0'; //给密码补斜杠零,表示字符串结束
printf("\n\t请再次输入登陆密码(最多9位):");
for (j = 0; j < 9 && ((pwd1[j] = _getch()) != 13); ++j)
printf("*");
pwd1[j] = '\0'; //给密码补斜杠零,表示字符串结束
if ((strcmp(pwd, pwd1)) == 0)
break;
else
printf("两次密码不同,请重新输入!\n\n");
}
//将密码保存在配置文件中
if ((fp1 = fopen("config.txt", "w")) == NULL)
{
printf("\n文件打开失败,请按任意键退出");
system("pause");
exit(0);
}
else
{
i = 0;
while (pwd[i] != 0)
{
putc(pwd[i], fp1);
i++;
}
}
fclose(fp1);
printf("\n\n系统配置成功,请退出系统,重新登录:");
system("pause");
exit(1);
}
else //从配置文件文件中读取密码,进行匹配
{
i = j = 0;
while (!feof(fp) && i < 9)
{
pwd[i++] = getc(fp);
}
pwd[i] = '\0';
if (i >= 9)
i--;
while (pwd[i] != -1 && i >= 0)
i--;
pwd[i] = '\0';
strcpy(password,pwd);
}
fclose(fp);
}
//登录检测
void Login()
{
int i = 5, j;
char pwd[MAX_SIZE];
while (i)
{
printf("请输入密码:");
for (j = 0; j < 9 && ((pwd[j] = _getch()) != 13); ++j)
printf("*");
pwd[j] = '\0';
if (strcmp(pwd, password))
{
printf("\n密码错误,请重新输入......\n");
getchar();
system("cls");
i--;
}
else
break;
}
if (!i)
{
printf("非法用户,请退出....\n");
getchar();
exit(1);
}
}
//菜单显示
void Menu()
{
printf("\t\t员工管理系统\n");
printf("\t\t1.添加员工信息\n");
printf("\t\t2.查找员工信息\n");
printf("\t\t3.删除员工信息\n");
printf("\t\t4.显示员工信息\n");
printf("\t\t5.修改员工信息\n");
printf("\t\t6.统计员工信息\n");
printf("\t\t7.重置系统密码\n");
printf("\t\t0.退出系统\n");
}
接下来给大家对于数据的保存,读出操作,写入操作,若初次操作,文件不存在,将gfirst设置为1,表示初次打开,不存在该文件,直接退出。读取操作从头读取,将文件中的数据全部读取,保存到栈中,准备被操作,
#include"emp.h"
//保存信息,将信息保存到文本文件中
void SaveDate()
{
FILE *fp = fopen("text.txt", "w");
Person *emp;
emp = emp_first;
if (gsave == 0)
return;
assert(fp != NULL);
while (emp)
{
fprintf(fp, READFORMAT, READDATE);
emp = emp->next;
}
gsave = 0;
fclose(fp);
}
//读取数据,若初次登录则进行初始化吧,否则直接挂链,储存在栈中
void ReadDate()
{
FILE *fp = fopen("text.txt", "r");
Person *emp;
if (fp == NULL) //系统第一次打开
{
gfirst = 1;
return;
}
while (!feof(fp))
{
emp = (Person *)malloc(sizeof(Person));
assert(emp != NULL);
int res = fscanf(fp, WRITEFORMAT, WRITEDATE);
if (res == EOF)
break;
if (emp_first == NULL) //如果为空链,则头尾指针指向当前元素
{
emp_first = emp;
emp_end = emp;
}
else //否则,尾插挂链,将数据储存
{
emp_end->next = emp;
emp_end = emp;
}
emp_end->next = NULL;
}
gfirst = 0;
fclose(fp);
}
接着给大家给出主体功能函数包括(增删改查修统)6大基本部分,还有重置密码
#include"emp.h"
//添加员工
void AddPerson()
{
Person *temp;
int i = 1;
char choice;
while (1)
{
temp = (Person *)malloc(sizeof(Person));
assert(temp != NULL);
printf("请输入第%d个员工的信息\n",i);
printf("-------------------------\n");
printf("工号:");
scanf("%s", temp->Num);
printf("姓名:");
scanf("%s", temp->Name);
printf("职称:");
scanf("%s",temp->Duty);
printf("性别:");
scanf("%s", temp->Sex);
printf("年龄:");
scanf("%d", &(temp->Age));
printf("文化程度:");
scanf("%s", temp->Edu);
printf("工资:");
scanf("%d", &(temp->Tel_offer));
printf("电话:");
scanf("%s", temp->Tel);
printf("QQ:");
scanf("%s", temp->QQ);
printf("地址:");
scanf("%s", temp->Addr);
temp->next = NULL; //对成员完成添加
i++;
if (emp_first == NULL)
{
printf("链表为空\n");
emp_first = temp;
emp_end = temp;
}
else
{
printf("此链表有数据\n");
emp_end->next = temp;
emp_end = temp;
}
printf("----------------------------------\n");
printf("是否需要继续输入?(y/n)");
fflush(stdin);
choice = getchar();
if (choice == 'y' || choice == 'Y')
{
printf("继续输入\n");
system("pause");
}
else
{
printf("退出重选\n");
system("pause");
break;
}
}
gfirst = 0; //表示链表中已经有元素
gsave = 1; //表明有元素更改
SaveDate();
}
//寻找员工
void FindPerson()
{
assert(emp_first != NULL);
Person *emp=NULL;
printf("请输入你需要查找的方式(1.姓名,2.工号,3.电话,4.QQ)>");
int i;
scanf("%d", &i);
switch (i)
{
case 1:
emp=FindByName(emp_first);
break;
case 2:
emp=FindByNum(emp_first);
break;
case 3:
emp=FindByTel(emp_first);
break;
case 4:
emp=FindByQQ(emp_first);
break;
default:
printf("输入错误\n");
break;
}
if (emp == NULL)
{
printf("此人不存在,请重新操作\n");
getchar();
exit(0);
}
else
{
printf(READFORMAT,READDATE);
}
system("pause");
}
//删除员工
void DelPerson()
{
assert(emp_first != NULL);
int i = 0, find = 0;
Person *emp1, *emp2;
char name[SIZE];
char choice;
system("cls");
printf("\n请输入你需要删除的员工姓名:");
scanf("%s", name);
emp1 = emp_first;
emp2 = emp1;
while (emp1!=NULL)
{
if (strcmp(emp1->Name, name) == 0)
{
find = 1;
system("cls");
printf("确认要删除改员工:");
printf("------------------------------\n");
printf("工号:");
printf("%s\n", emp1->Num);
printf("姓名:");
printf("%s\n", emp1->Name);
printf("职称:");
printf("%s\n", emp1->Duty);
printf("性别:");
printf("%s\n", emp1->Sex);
printf("年龄:");
printf("%d\n", emp1->Age);
printf("文化程度:");
printf("%s\n", emp1->Edu);
printf("工资:");
printf("%d\n", emp1->Tel_offer);
printf("电话:");
printf("%s\n", emp1->Tel);
printf("QQ:");
printf("%s\n", emp1->QQ);
printf("住址:");
printf("%s\n", emp1->Addr);
printf("------------------------------\n");
printf("真的要删除该员工吗?(y/n)");
scanf("%c", &choice);
if (choice == 'y' || choice == 'Y')
{
if (emp1 == emp_first)
{
emp_first = emp1->next;
}
else
{
emp2->next = emp1->next;
}
free(emp1);
gsave = 1;
SaveDate();
return;
}
}
else
{
emp2 = emp1;
emp1 = emp1->next;
}
}
if (!find)
{
printf("\n------------------\n");
printf("未找到姓名为%s的员工\n", name);
printf("\n");
system("pause");
}
}
//显示所有员工
void ShowPerson()
{
assert(emp_first != NULL);
Person *temp = (Person *)malloc(sizeof(Person));
temp = emp_first;
if (emp_first == NULL)
{
printf("没有任何人员,请退出\n");
exit(0);
}
printf("\n 员工列表:\n");
while (temp != NULL)
{
printf("----------------------------\n");
printf("工号:");
printf("%s\n", temp->Num);
printf("姓名:");
printf("%s\n", temp->Name);
printf("职称:");
printf("%s\n", temp->Duty);
printf("性别:");
printf("%s\n", temp->Sex);
printf("年龄:");
printf("%d\n", temp->Age);
printf("文化程度:");
printf("%s\n", temp->Edu);
printf("工资:");
printf("%d\n", temp->Tel_offer);
printf("电话:");
printf("%s\n", temp->Tel);
printf("QQ:");
printf("%s\n", temp->QQ);
printf("住址:");
printf("%s\n", temp->Addr);
printf("------------------------------\n");
printf("\n\n");
temp=temp->next;
}
getchar();
}
//修改员工信息
void ModifyPerson()
{
assert(emp_first != NULL);
Person *emp1 = emp_first;
char Name[SIZE];
int choice;
printf("\n请输入你需要修改的员工名称:");
scanf("%s",Name);
while (emp1!=NULL)
{
if (strcmp(Name,emp1->Name) == 0)
break;
else
emp1=emp1->next;
}
if (emp1==NULL)
{
printf("此人员不存在,请退出\n");
system("pause");
return;
}
else
{
printf("\n请输入你需要修改的项目\n");
printf("---------------------\n");
printf("1.修改职务 2.修改文化程度\n");
printf("3.修改工资 4.修改电话\n");
printf("5.修改住址 6.修改QQ号码\n");
printf("0.返回\n");
printf("------------------------\n");
printf("请选择:");
scanf("%d", &choice);
switch (choice)
{
case 0:
break;
case 1:
printf("请输入修改后的职务:");
scanf("%s", emp1->Duty);
break;
case 2:
printf("请输入修改后的文化程度:");
scanf("%s", emp1->Edu);
break;
case 3:
printf("请输入修改后的工资:");
scanf("%d", &(emp1->Tel_offer));
break;
case 4:
printf("请输入修改后的电话:");
scanf("%s", emp1->Tel);
break;
case 5:
printf("请输入修改后的地址:");
scanf("%s", emp1->Addr);
break;
case 6:
printf("请输入修改后的QQ:");
scanf("%s", emp1->QQ);
break;
default:
printf("输入错误,请重新选择");
getchar();
break;
}
gsave = 1;
SaveDate();
printf("\n修改完成,请按任意键继续\n");
system("pause");
return;
}
}
//统计员工信息
void SummaryPerson()
{
assert(emp_first!= NULL);
Person *emp1=emp_first;
int num = 0, man = 0, woman = 0;
int sum=0;
while (emp1)
{
num++;
sum=sum+emp1->Tel_offer;
if (strcmp(emp1->Sex, "男") == 0)
man++;
else
woman++;
emp1 = emp1->next;
}
printf("\n员工统计信息\n");
printf("---------------------\n");
printf("总人数:%d\n", num);
printf("男:%d\n女:%d\n", man, woman);
printf("工资总额:%d\n", sum);
printf("------------------------\n");
system("pause");
return;
}
//修改密码
void ResetPsw()
{
char pwd[MAX_SIZE], pwd1[MAX_SIZE];
FILE *fp;
int i;
fp = fopen("config.txt", "w");
if (fp == NULL)
{
printf("文件打开失败,请退出\n");
system("pause");
exit(1);
}
printf("请输入旧密码>");
for (i = 0; (pwd[i] = _getch()) != 13; i++)
printf("*");
pwd[i] = '\0';
if (strcmp(pwd, password) != 0)
{
printf("\n 密码输入错误,请按任意键返回!\n");
getchar();
exit(1);
}
while (1)
{
printf("\n请输入新密码>");
int j;
for (j = 0; (pwd[j] = _getch()) != 13; j++)
printf("*");
pwd[j] = '\0';
printf("\n请再次输入密码>");
for (j = 0; (pwd1[j] = _getch()) != 13; j++)
printf("*");
pwd1[j] = '\0';
if (strcmp(pwd, pwd1) != 0)
{
printf("两次输入密码不同,请重新输入\n");
getchar();
system("cls");
}
else
break;
}
fclose(fp);
fp = fopen("config.txt", "w");
if (fp == NULL)
{
printf("文件打开失败,清退出!\n");
getchar();
exit(1);
}
else{
i = 0;
while (pwd[i] != '\0')
{
putc(pwd[i], fp);
i++;
}
fclose(fp);
}
}
最后呐,给出查找函数
#include"emp.h"
//按姓名查找
Person* FindByName(Person *emp)
{
char Name[SIZE];
printf("请输入你需要查找的人员的姓名>");
scanf("%s", Name);
Person *temp = emp;
while (temp != NULL)
{
if(strcmp(Name, temp->Name)==0)
break;
else
temp=temp->next;
}
return (temp == NULL) ? NULL : temp;
}
//按工号查找
Person* FindByNum(Person *emp)
{
char Num[SIZE];
printf("请输入你需要查找的人员的工号>");
scanf("%s", Num);
Person *temp = emp;
while (temp != NULL)
{
if (strcmp(Num, temp->Num) == 0)
break;
else
temp=temp->next;
}
return (temp == NULL) ? NULL : temp;
}
//按电话查找
Person* FindByTel(Person *emp)
{
char Tel[T_MAX];
printf("请输入你需要查找的人员的电话>");
scanf("%s",Tel);
Person *temp = emp;
while (temp != NULL)
{
if (strcmp(Tel, temp->Tel) == 0)
break;
else
temp=temp->next;
}
return (temp == NULL) ? NULL : temp;
}
//按 QQ查找
Person* FindByQQ(Person *emp)
{
char QQ[T_MAX];
printf("请输入你需要查找的人员的QQ>");
scanf("%s", QQ);
Person *temp = emp;
while (temp != NULL)
{
if (strcmp(QQ, temp->QQ) == 0)
break;
else
temp=temp->next;
}
return (temp == NULL) ? NULL : temp;
}
这个就是本次写的所有代码了。
最后的最后我就把这次写代码的一些心得说一下吧
1.return 与 exit () 的区别 #return是一个关键字,返回函数值;exit ()是一个函数; return是语言级的;exit ()是操作系统提供的函数; return表示函数退出;exit ()表示进程退出; 非主函数中调用return和exit效果很明显,但是在main函数中调用return和exit的现象就很模糊,多数情况下现象都是一致的; exit (0)表示正常运行程序并退出;exit (1)表示非正常运行导致退出;return 结束一个函数的执行,并将执行信息传递出来
2.给程序设置密码
3.设置密码
将设置完成的密码保存到文件中,以后登录时,直接从文件中再读入密码,但是直接读入是不正确的,原因是未将文件结尾的(EOF)的文件标识符去掉,也就是-1去掉
4.注意换行符的使用,尤其是在重置密码时,
5.还有一般情况下不要去碰宏定义,
6.对于工资等需要加和,求平均的数值,一般都需要给为整形,方便以后计算和处理
7.在全局变量中定义头指针和尾指针,因为对链表的操作,在每一次在执行中都会被用到
8.将文件的操作放在单独的一个c文件中,方便你拉出来单独调试,
9.对于链表的操作,一般都是通过他的next指针完成的,不能再傻逼的出现++的行为,不然内存越界,和程序奔溃就在前面等着你
10.还有文件内容一般用追加,会比较省时,但是你要是直接写入数据不多的情况下问题不大,但是数据过多,每一次修改都是一个比较大的麻烦事,
文件的读取每次都需要从头读到尾,将内容全部都存到链表中,等待操作,
11.查找的话需要单独写一个函数来执行,链表的遍历
12.初始化,如果第一次进入则设置密码,然后退出,重新进入系统,其他时候就直接输密码,密码正确就进入系统,不正确就退出系统,
13.检查登录,用strcmp函数来检测登录,检测完成后,将进入主界面,执行操作
14.功能函数,增删改查修统计,6大部分,稍微会一点链表就可以操作。
15.相比于用顺序表写,更加方便,而且 不用担心内存不够等问题,比较方便。
16.我在等老师的评价,准备做新一步的更改和变化。
这大概就是我这次写代码的全部过程了
希望各位大佬多多指点。