C 语言编写的人员管理系统(链表版)

该系统具有以下主要功能:

  1. 添加人员信息:在有空间的前提下,用户输入人员的工号、姓名、性别、联系电话和 QQ 号等信息,系统会自动检查编号的唯一性,确保不重复。
  2. 查找人员信息:提供按工号和姓名两种查找方式,找到后会显示相应人员的详细信息。
  3. 修改人员信息:可以按工号或姓名进行修改,修改时编号不能更改。
  4. 删除人员信息:同样支持按工号和姓名删除,删除前会进行确认。
  5. 统计人员数量:能给出当前公司人员的总数。
  6. 显示人员信息:可以展示全体人员的信息或指定单个人员的信息。
  7. 保存和读取文件:能将人员信息保存到指定文件,也能从文件中读取人员信息。
  8. 排序人员信息:提供插入排序和冒泡排序两种方式,可对人员按工号进行排序。
#include<stdio.h>
#include<stdlib.h>   //内存管理
#include<string.h>   //串操作
//数据元素结构
typedef struct
{	int  no;        //编号
	char name[20];  //姓名
	int sex;        //性别
	char tel[14];  //联系电话
	char qq[12];   //QQ号
}ElemType;  

 //链表表结构
typedef struct LNode{
    ElemType data;
    struct LNode *next;
}LNode;

void Edit(LNode *L);          //修改子菜单
void Delete(LNode *L) ;       //删除子菜单
void Search(LNode *head);       //查找子菜单
void Sort(LNode *head);         //排序子菜单

void DestroyList(LNode *head);       //销毁链表
void Add(LNode *head);               //添加人员
int Unique(LNode *head,int n) ;      //判别工号n是否已经存在
void PrintList(LNode *head);         ///显示功能
void Total(LNode *head) ;            //统计人员数目

void Edit_num(LNode *head);          //按编号修改
void Edit_name(LNode *head);         //按姓名修改
void Delete_num(LNode *head);          /按编号进行删除
void Delete_name(LNode *head);          /按姓名进行删除
void Save(LNode *head);                 /存文件
void Read(LNode *head);                  /读文件
void Search_num(LNode *head);             //按编号进行查找
void Search_name(LNode *head);             //按姓名进行查找

void SelectSort(LNode *head);             //选择排序
void BubbleSort(LNode *head);             //冒泡排序


int main()
{
	printf("                    ###     欢迎进入人员管理系统      ###\n");
    链表初始化
	LNode   *head;    ///
	head = (LNode *)malloc(sizeof(LNode));   //创建头结点
    head->next =NULL;

	int choice=1;
	while(choice!=0)
	{
		printf("ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("|                                                                             |\n");
		printf("|1.添加  2.查找  3.修改  4.统计  5.删除  6.显示  7.保存 8.读取  9.排序  0.返回|\n");
		printf("|                                                                             |\n");
		printf("ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("输入您操作的选项:");
	        scanf("%d",&choice);
        	switch(choice)
		{
			case 1:Add(head);  //添加人员信息
				   break;
			case 2:Search(head);//查找
				   break;	
			case 3:Edit(head);//调用修改二级菜单
				   break;
			case 4:Total(head);//统计
				   break;
			case 5:Delete(head);//调用删除菜单
				   break;
			case 6:PrintList(head);//显示
				   break;
			case 7:Save(head);                 /存文件
				   break;
		    case 8:Read(head);                  /读文件
				   break;
			case 9:Sort(head);         //排序三级子菜单//排序
				   break;
			case 0:DestroyList(head);   //销毁链表
				   printf("退出成功!\n");
				   break;
			default:
				   printf("无此选项,请重试!\n");
				   break;
		}
	}

	printf("                     ooooo欢迎您使用本系统!ooooo\n");
    return 0;
}
///销毁链表函数
void DestroyList(LNode *head)
{  LNode *q,*p=head;//让p指向头结点
   while(p!=NULL)
	{    q=p->next;//让q指向头结点的后续结点
         free(p);//删除p
         p=q; 
    }
    head=NULL;
}
添加人员信息
void Add(LNode *head)         
{
   LNode *q,*p=head;    
   //找链表尾部地址p
   q=p->next;
   while(q!=NULL)
	{    
        p=q;
		q=q->next; 
   }
    printf("正在添加人员......\n");
	q= (LNode *)malloc(sizeof(LNode)); //创建新结点
	q->next=NULL;
    printf("请输入数据(工号  姓名  性别(0或1) 联系电话  QQ号):\n");
	scanf("%d%s%d%s%s",&q->data.no,q->data.name , &q->data.sex , q->data.tel  ,q->data.qq);
	
    if(Unique(head,q->data.no)) 
	{
	  printf("该编号已存在,添加失败!\n");
	  free(q);
	  return;
	}

    p->next=q;
    printf("添加成功!!!\n\n");
}
/判别工号唯一性,1---不唯一;0---唯一
int Unique(LNode *head,int n)   
{

    LNode *p=head->next;
    while(p!=NULL)
    { if(p->data.no==n) return 1;
      p=p->next ;
    }
    return 0;

}
///显示功能
void PrintList(LNode *head)         
{   if (!head->next) {printf("没有人员信息!\n");return;}
	LNode *p;
    p=head->next;
    printf("学号    姓名    性别    电话    QQ号\n");
    printf("-----------------------------------------------------\n");
    while(p!=NULL)
    {   printf("%d\t%s\t",p->data.no,p->data.name);
        if(p->data.sex)   printf("男      ");  else   printf("女      ");
        printf("%s\t%6s\n",p->data .tel,p->data.qq);
    printf("-----------------------------------------------------\n");
    p=p->next ;
    }
}
//统计人员数目
void Total(LNode *head)         
{
    LNode *p;
    int count=0;
    p=head->next;
    while(p!=NULL)
    { count++;
      p=p->next ;
    }
    printf("人员总人数为:%d人\n",count);
}

修改功能/
/
void Edit(LNode *head)          //修改二级子菜单
{
    if (!head->next) {printf("没有人员信息!\n");return;}
	int choice=1;	
	do{
		printf("                    ooooo修改ooooo\n");
		printf("||                                                        ||\n");
		printf("||        1 : 按工号       2 : 按姓名       0 :退出       ||\n");
		printf("||                                                        ||\n");
		printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:Edit_num(head);
				   break;
			case 2:Edit_name(head);
				   break;
			case 0:printf("您已安全退出!\n");
				   break;
			default:printf("没有此选项,请重选!\n");
				    break;
		}
	}while(choice!=0);
}

void Edit_num(LNode *head)        //按编号修改
{
  int x;
  printf("请输入要修改的人员的编号:");
  scanf("%d",&x);
  LNode *p=head->next; 
  
  while(p!=NULL)
    { 
	  if(p->data.no==x) 
	  {
		printf("请输入数据(工号  姓名  性别(0或1) 联系电话  QQ号):\n");
	    scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel  ,p->data.qq);
	    while(p->data.no!=x)
		  {
			printf("编号不能修改!");
		    printf("请输入数据(工号  姓名  性别(0或1) 联系电话  QQ号):\n");
	        scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel  ,p->data.qq);
		  }
		printf("修改成功!\n");
		return;		
	  }
      p=p->next ;
    }  
   printf("该人员不存在!\n");
}
void Edit_name(LNode *head)     //按姓名修改----存在重名现象
{
  char nam[20],c1;
  printf("请输入要编辑的人员的姓名:");
  scanf("%s",nam);
  LNode *p=head->next; 
  
  while(p!=NULL)
  { 
    if(strcmp(p->data.name,nam)==0) 
	{ int n=p->data.no;
      printf("%d\t%s\t",p->data.no,p->data.name);
      if(p->data.sex)   printf("男      ");  else   printf("女      ");
      printf("%s\t%6s\n",p->data .tel,p->data.qq);
      printf("要修改这条记录吗?(是:y/Y,否:n/N):");
	  fflush(stdin); 
	  scanf("%c",&c1);
	  if(c1=='y'||c1=='Y') 
	  { printf("请输入数据(工号  姓名  性别(0或1) 联系电话  QQ号):\n");
	    scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel  ,p->data.qq);
	    while(p->data.no!=n)
		{
		printf("编号不能修改!");
	    printf("请输入数据(工号  姓名  性别(0或1) 联系电话  QQ号):\n");
	    scanf("%d%s%d%s%s",&p->data.no,p->data.name , &p->data.sex , p->data.tel  ,p->data.qq);
		}
	    printf("修改成功!\n");
	    return;	
	  }
	 }
     p=p->next ;
  }
  printf("该人员不存在!\n");
}


删除功能/
/
void Delete(LNode *head)             //删除子菜单
{
    if (!head->next) {printf("没有技术人员信息!\n");return;}
	int choice;	
	do{
    	        printf("                    ooooo删除ooooo\n");
		printf("||                                                        ||\n");
		printf("||        1 : 按工号       2 : 按姓名       0 :退出       ||\n");
		printf("||                                                        ||\n");
		printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
			case 1:Delete_num(head);
				   break;
			case 2:Delete_name(head);
				   break;
			case 0:printf("您已安全退出删除功能!\n");
				   break;
			default:printf("没有此选项,请重选!\n");
				    break;
		}
	}while(choice!=0);
}

void Delete_num(LNode *head)          /按工号进行删除
{ 
	char c1;
	int x;
    printf("请输入要删除的人员的编号:");
    scanf("%d",&x);
    LNode *q=head,*p; //q前驱结点,p被删除结点
  
    while(q->next!=NULL)
    {   p=q->next;
	if(p->data.no==x) 
	  {
	   printf("%d\t%s\t",p->data.no,p->data.name);
           if(p->data.sex)   printf("男      ");  else   printf("女      ");
           printf("%s\t%6s\n",p->data .tel,p->data.qq);                   
	   break;
	  }
	  q=q->next;

	}	 
        if(q->next==NULL)
	{
	  printf("无此人员!");
          return ;
	} 
	
        printf("是否删除此项(是:y/Y,否:n/N):");
	fflush(stdin); 
	scanf("%c",&c1);
	if(c1=='y'||c1=='Y')
	{
		q->next=p->next;   //删除p结点
		free(p);           //释放空间
		printf("删除成功!\n");
		return ;
	}
	else
		printf("没有删除该人员!\n");
}


void Delete_name(LNode *head)          /按姓名进行删除----姓名可能相同
{
	char c1;
	char nam[20];
	printf("请输入要删除的人员的姓名:");
    scanf("%s",nam);
    LNode *q=head,*p; //q前驱结点,p被删除结点
  
    while(q->next!=NULL)
    { p=q->next;
	  if(strcmp(p->data.name,nam)==0) 
	  {
	   printf("%d\t%s\t",p->data.no,p->data.name);
       if(p->data.sex)   printf("男      ");  else   printf("女      ");
       printf("%s\t%6s\n",p->data .tel,p->data.qq);                   
	   printf("要删除这条记录吗?(是:y/Y,否:n/N):");
	   fflush(stdin); 
	   scanf("%c",&c1);
	   if(c1=='y'||c1=='Y') break;
	  }
	  q=q->next;

	}	 
    if(q->next==NULL)
	{
	  printf("无此人员!");
          return ;
	} 	
    printf("是否删除此项(是:y/Y,否:n/N):");
	fflush(stdin); 
	scanf("%c",&c1);
	if(c1=='y'||c1=='Y')
	{
		q->next=p->next;   //删除p结点
		free(p);           //释放空间
		printf("删除成功!\n");
		return ;
	}
	else
		printf("没有删除该人员!\n");
}

///
void Save(LNode *head)                  /存文件
{
   FILE *fp = NULL;
   fp = fopen("D:\\人员管理.txt", "w");
   if(!fp)
   {    printf("文件打开出错\n");
        return;
   }
   LNode *p;
   p=head->next;
   while(p!=NULL)
   {
		fprintf(fp,"\n%d\t",p->data.no);		//写进磁盘保存,以下同理
		fprintf(fp,"%s\t",p->data.name);
		fprintf(fp,"%d\t",p->data.sex);
		fprintf(fp,"%s\t",p->data.tel);
		fprintf(fp,"%s",p->data.qq);
	    p=p->next;
	}
      
   printf("保存成功!\n");
   fclose(fp);

}

void Read(LNode *head)                  /读文件
{   
	//清空所有数据结点
   LNode *q,*p=head->next;//让p指向一个数据结点
   while(p!=NULL)
	{    q=p->next;//让q指向头结点的后续结点
         free(p);//删除p
         p=q; 
    }
    head->next=NULL;
   /
	//打开文件
    FILE *fp = NULL;
    fp = fopen("D:\\人员管理.txt", "r");
    if(!fp)
    {    printf("文件打开出错\n");
        return;
    }
	//尾插入法构建链表
	q=head;
   while(!feof(fp))
   {
   p=(LNode *)malloc(sizeof(LNode));   //创建数据结点
   fscanf(fp, "%d%s%d%s%s", &p->data.no,p->data.name,&p->data.sex,p->data.tel,p->data.qq);
   q->next=p;
   q=p;
   }
   p->next=NULL;
   
   printf("读取成功!\n");
   fclose(fp);
}
//

void Search(LNode *head)              //查找子菜单
{
    if (!head->next) {printf("没有人员信息!\n");return;}
	int choice;
	do{
    	printf("                    ooooo查找ooooo\n");
		printf("||                                                        ||\n");
		printf("||        1 : 按工号       2 : 按姓名       0 :退出       ||\n");
		printf("||                                                        ||\n");
		printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
            case 1:Search_num(head);
				   break;
			case 2:Search_name(head);
				   break;
			case 0:printf("您已安全退出查找功能!\n");
				   break;
			default:printf("没有此选项,请重选!");
				   break;
		}
	}while(choice!=0);
}


void Search_num(LNode *head)                        //按编号进行查找
{
  	int x;
    printf("请输入要查找的人员的工号:");
    scanf("%d",&x);
    LNode *p=head->next;  
  
    while(p!=NULL)
    {
	  if(p->data.no==x) //找到后,显示该记录信息
	  {
	  	printf("%d\t%s\t",p->data.no,p->data.name);
        if(p->data.sex)   printf("男      ");  else   printf("女      ");
        printf("%s\t%6s\n",p->data .tel,p->data.qq);                   
		break;
	  }
	  p=p->next;

	}	 
    if(p==NULL)
	{
	    printf("无此工号的人员!");
        return ;
	} 
}

void Search_name(LNode *head)                        //按姓名进行查找--顺序查找--可能重名
{
    char nam[20];
	int flag=0;
    printf("请输入要查找的人员的姓名:");
    scanf("%s",nam);
    LNode *p=head->next;  
  
    while(p!=NULL)
    {
	if(strcmp(p->data.name,nam)==0) //找到后,显示该记录信息
	{  if(flag) 
		   printf("oooooooooooo又找到了一个,其信息为:oooooooooooo\n");
	    else 
		   printf("oooooooooooo   找到了,其信息为:   oooooooooooo\n");
	  	printf("%d\t%s\t",p->data.no,p->data.name);
        if(p->data.sex)   printf("男      ");  else   printf("女      ");
        printf("%s\t%6s\n",p->data .tel,p->data.qq);                   
		flag=1;
	  }
	  p=p->next;

    }	 
    if(!flag) printf("该人员不存在!\n");
}
//

void Sort(LNode *head)              //排序子菜单
{
    if (!head->next) {printf("没有人员信息!\n");return;}
	int choice;
	do{
    	printf("                    ooooo查找ooooo\n");
		printf("||                                                        ||\n");
		printf("||      1 : 选择排序      2 : 冒泡排序      0 :退出       ||\n");
		printf("||                                                        ||\n");
		printf("oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo\n");
		printf("请输入您的选择:");
		scanf("%d",&choice);
		switch(choice)
		{
            case 1:SelectSort(head);
				   break;
			case 2:BubbleSort(head);
				   break;
			case 0:printf("您已安全退出排序功能!\n");
				   break;
			default:printf("没有此选项,请重选!");
				   break;
		}
	}while(choice!=0);
}

void SelectSort(LNode *head)    //直接选择排序
{
    LNode *p,*q,*min;
    ElemType t;
    p=head->next;  //p指向第一个数据结点
    while (p!=NULL)
	{
		min=p;
		q=p->next;
		while(q!=NULL)    //找最小值结点地址min
		{
			if(q->data.no<min->data.no)
				min=q;
			q=q->next;
		}
		if(min!=p)   //若不是最前面,则交换
		{    t=p->data;
		     p->data=min->data;
	             min->data=t;
		}
		p=p->next;
	}
   printf("排序完毕!\n");
   PrintList(head); 

}

void BubbleSort(LNode *head)    //冒泡排序
{   ElemType t;
    LNode *tail,*p,*next;//tail代表链表每一次排序后的未排序链表的最后一个节点
    if(head->next==NULL)
    { printf("无记录!\n");
      return;
     }
    for(p=head;p->next!=NULL;p=p->next);//找尾结点地址p
    tail=p;

    while(tail!=head->next)
    {
        for(p = head->next ;p!=tail;p=p->next)
        {
            if(p->data.no>p->next->data.no)//比较p节点和p->next节点的data大小
            {
                t=p->data;p->data=p->next->data;p->next->data=t;
            }
            next=p;
        }
        tail = next;
    }
    printf("排序完毕!\n");
    PrintList(head); 
}

  • 6
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级小狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值