
//文件包含
#include
#include
#include
#include
//学生信息长度宏定义
#define MAX_ID 12 //学号最大长度
#define MAX_NAME 11 //姓名最大长度
#define MAX_BIRTH 11 //出生年月日最大长度
#define MAX_ADDR 101 //籍贯最大长度
#define MAX_TEL 12 //手机号码最大长度
//系统菜单选项宏定义
#define EXIT 0 //退出系统
#define INPUT 1 //导入学生信息
#define OUTPUT 2 //游览学生信息
#define SEARCH 3 //查询学生信息
#define UPDATE 4 //修改学生信息
#define DELETE 5 //删除学生信息
#define RANk 6 //输出人数籍贯前三地区
#define SAVE 7 //信息存盘
#define TESHU 8 //输出湖南籍的学生相关信息
//学生籍贯信息查找方式宏定义
#define SEARCH_ID 1 //按学号查找
#define SEARCH_NAME 2 //按姓名查找
#define SEARCH_ADDR 3 //按籍贯查找
//学生籍贯信息结构体
typedef struct _StuInfo
{
char id[MAX_ID]; //学号
char name[MAX_NAME]; //姓名
char shenfen[100]; //身份证号
char birth[MAX_BIRTH]; //出生年月
char addr[MAX_ADDR]; //籍贯
char tel[MAX_TEL]; //手机号码
}StuInfo;
//学生籍贯信息单链表结构体
typedef struct _StuNode //链表结点
{
StuInfo stu;
struct _StuNode *next;
}StuNode;
typedef StuNode* StuList; //链表
//全局变量定义,用于保存所有联系人信息的单链表
StuList student=NULL; //初始化链表为空
//人机界面操作函数列表
void ShowMenu(); //人机界面函数
void AddStu(); //导入学生信息
void DeleteStu(); //删除学生信息
void SearchStu(); //查询学生信息
void SearchStuID(); //按学号查找
void SearchStuName(); //按姓名查找
void SearchStuAddr(); //按籍贯查找
void UpdateStu(); //修改学生信息
void OutputStu(); //游览学生信息
void RankStu(); //籍贯排序并输出前三地区
void Teshu(); //输出湖南籍的学生相关信息
void Save(); //信息存盘
void Exit(); //退出系统
//辅助函数列表
void BubbleSort(); //链表冒泡排序
void ReadFile(); //从文件读出学生信息
void WriteFile(); //将学生信息写入文件
//查找学生在系统是否存在,存在返回1,不存在返回0
int FindStu(char* id);
void ShowMenu()
{
int typeID=0;
ReadFile(); //启动程序前从文件student.txt读出通讯录中联系人信息
while(1)
{
system("cls"); //清屏
printf("nn");
printf("ttt===================学生籍贯信息管理系统===================n");
printf("ttt* 作者:张博涵 班级:电子信息2班 学号:2021329600057 *n");
printf("ttt* *n");
printf("ttt* 1>. 录入学生的相关信息 *n");
printf("ttt* 2>. 全部学生的相关信息 *n");
printf("ttt* 3>. 查找某个学生的信息 *n");
printf("ttt* 4>. 修改某个学生的信息 *n");
printf("ttt* 5>. 删除某个学生的相关信息 *n");
printf("ttt* 6>. 统计输出学生数量前三籍贯地区 *n");
printf("ttt* 7>. 保存学生信息 *n");
printf("ttt* 8>. 输出湖南籍贯的学生相关信息 *n");
printf("ttt* 0>. 退出管理系统 *n");
printf("ttt* 欢迎使用本系统! *n");
printf("ttt=====================================================n");
printf("ttt输入选项,按回车进入选项: n");
printf("->请选择操作:");
scanf("%d",&typeID);
if(typeID == EXIT)
{
WriteFile(); //程序退出前将学生籍贯信息导入文件
Exit(); //退出系统
break;
}
switch(typeID)
{
case 1:
system("cls");
AddStu(); //导入学生信息
system("pause"); //程序暂停
break;
case 2:
system("cls");
OutputStu(); //游览学生信息
system("pause");
break;
case 3:
SearchStu(); //查询学生信息
break;
case 4:
system("cls");
UpdateStu(); //修改学生信息
system("pause");
break;
case 5:
system("cls");
DeleteStu(); //删除学生信息
system("pause");
break;
case 6:
system("cls");
RankStu(); //籍贯排序
system("pause");
break;
case 7:
system("cls");
Save(); //信息存盘
system("pause");
break;
case 8:
system("cls");
Teshu(); //输出湖南籍贯学生
system("pause");
break;
default:
printf("输入有误!n");
system("pause");
break;
}
}
}
void AddStu()
{
StuNode *p = (StuNode*)malloc(sizeof(StuNode));//分配存储空间
printf("****************************************n");
printf(" 请输入学生籍贯信息 n");
printf("========================================n");
printf(" 1>.请输入学号 n");
scanf("%s",p->stu.id);
while(FindStu(p->stu.id)==1)
{
printf("此学生信息已经存在,请重新输入n");
scanf("%s",p->stu.id);
}
printf("========================================n");
printf(" 2>.请输入姓名 n");
scanf("%s",p->stu.name);
printf("========================================n");
printf(" 3>.请输入出生日期(格式为1984-01-10) n");
scanf("%s",p->stu.birth);
printf("========================================n");
printf(" 4>.请输入身份证号码 n");
scanf("%s",p->stu.shenfen);
printf("========================================n");
printf(" 5>.请输入籍贯 n");
scanf("%s",p->stu.addr);
printf("========================================n");
printf(" 6>.请输入手机号码 n");
scanf("%s",p->stu.tel);
p->next = student;
student = p;
printf("========================================n");
printf(" 学生籍贯信息添加成功! n");
printf("**************************************n");
}
void DeleteStu()
{
StuNode *pre=student; //前一结点
StuNode *p=student; //当前结点
char id[MAX_ID];
printf("*******************************n");
printf("**请输入要删除学生的学号:n->");
scanf("%s",id);
while(p) //查找待删除结点
{
if(strcmp(p->stu.id,id)==0)
break;
pre=p;
p=p->next;
}
if(!p)
printf("** 此学生不存在! **n");
else
{
if(p==student) student=p->next;
else pre->next=p->next;
free(p);
printf("** 删除成功! **n");
}
printf("****************************************n");
}
void SearchStu()
{
int type,flag=1;
while(flag)
{
system("cls");
printf("****************************n");
printf("* 1 - 按学号查找 *n");
printf("* 2 - 按姓名查找 *n");
printf("* 3 - 按籍贯查找 *n");
printf("->选择查找方式:");
printf("****************************n");
scanf("%d",&type);
switch(type)
{
case SEARCH_ID:
system("cls");
SearchStuID(); //按学号查找
flag=0;
break;
case SEARCH_NAME:
system("cls");
SearchStuName(); //按姓名查找
flag=0;
break;
case SEARCH_ADDR:
system("cls");
SearchStuAddr(); //按籍贯查找
flag=0;
break;
default:
printf("输入有误!n");
break;
}
system("pause");
}
}
void SearchStuID()
{
StuNode *p=student;
char id[MAX_ID];
printf("****************************n");
printf("**请输入要查找学生的学号 :n->");
scanf("%s",id);
while(p) //检查待查找学生是否存在
{
if(strcmp(p->stu.id,id)==0)
break;
p=p->next;
}
if(!p)
{
printf("** 此学生不存在! **n");
printf("*******************************n");
}
else //待查找学生存在则输出信息
{
printf("****************************n");
printf("* 学生籍贯信息 *n");
printf("****************************n");
printf("$学 号 :%sn",p->stu.id);
printf("$姓 名 :%sn",p->stu.name);
printf("$身份证号码 :%sn",p->stu.shenfen);
printf("$出生日期:%sn",p->stu.birth);
printf("$籍 贯 :%sn",p->stu.addr);
printf("$手机号码:%sn",p->stu.tel);
printf("****************************n");
}
}
void SearchStuName()
{
StuNode *p=student;
char name[MAX_NAME];
printf("****************************n");
printf("**请输入要查找学生的姓名 :n->");
scanf("%s",name);
while(p) //检查待查找学生是否存在
{
if(strcmp(p->stu.name,name)==0)
break;
p=p->next;
}
if(!p)
{
printf("** 此学生不存在! **n");
printf("*******************************n");
}
else //待查找学生存在则输出信息
{
printf("****************************n");
printf("* 学生籍贯信息 *n");
printf("****************************n");
printf("$学 号 :%sn",p->stu.id);
printf("$姓 名 :%sn",p->stu.name);
printf("$身份证号码 :%sn",p->stu.shenfen);
printf("$出生日期:%sn",p->stu.birth);
printf("$籍 贯 :%sn",p->stu.addr);
printf("$手机号码:%sn",p->stu.tel);
printf("****************************n");
}
}
void SearchStuAddr()
{
StuNode *p=student;
char addr[MAX_NAME];
printf("****************************n");
printf("**请输入要查找学生的籍贯 :n->");
scanf("%s",addr);
while(p) //检查待查找学生是否存在
{
if(strcmp(p->stu.addr,addr)==0)
break;
p=p->next;
}
if(!p)
{
printf("** 此学生不存在! **n");
printf("*******************************n");
}
else //待查找学生存在则输出信息
{
printf("****************************n");
printf("* 学生籍贯信息 *n");
printf("****************************n");
printf("$学 号 :%sn",p->stu.id);
printf("$姓 名 :%sn",p->stu.name);
printf("$身份证号码 :%sn",p->stu.shenfen);
printf("$出生日期:%sn",p->stu.birth);
printf("$籍 贯 :%sn",p->stu.addr);
printf("$手机号码:%sn",p->stu.tel);
printf("****************************n");
}
}
void UpdateStu()
{
StuNode *p=student;
char id[MAX_ID];
printf("****************************n");
printf("**请输入要更新学生的学号 :n->");
scanf("%s",id);
while(p) //查找待修改结点
{
if(strcmp(p->stu.id,id)==0)
break;
p=p->next;
}
if(!p)
{
printf("** 此学生不存在! **n");
printf("*******************************n");
}
else
{
printf("-$原姓名:%sn",p->stu.name);
printf("->新姓名:");
scanf("%s",p->stu.name);
printf("-$原出生日期:%sn",p->stu.birth);
printf("->新出生日期:");
scanf("%s",p->stu.birth);
printf("-$原身份证号码:%sn",p->stu.shenfen);
printf("->新身份证号码:");
scanf("%s",p->stu.shenfen);
printf("-$原联系地址:%sn",p->stu.addr);
printf("->新联系地址:");
scanf("%s",p->stu.addr);
printf("-$原手机号码:%sn",p->stu.tel);
printf("->新手机号码:");
scanf("%s",p->stu.tel);
printf("** 修改成功! **n");
printf("*******************************n");
}
}
void OutputStu()
{
int i=0;
StuNode *p=student;
if(!p) //链表为空
{
printf("****************************n");
printf("** 系统中无学生人记录 **n");
printf("****************************n");
return;
}
while(p)
{
printf("**********************************n");
printf("* 学生%d信息 *n",++i);
printf("**********************************n");
printf("****************************n");
printf("* 学生籍贯信息 *n");
printf("****************************n");
printf("$学 号 :%sn",p->stu.id);
printf("$姓 名 :%sn",p->stu.name);
printf("$身份证号码:%sn",p->stu.shenfen);
printf("$出生日期:%sn",p->stu.birth);
printf("$籍 贯 :%sn",p->stu.addr);
printf("$手机号码:%sn",p->stu.tel);
printf("****************************n");
p=p->next;
}
}
void RankStu()
{
StuNode *p=student;
FILE* fp;
fp = fopen("student.txt", "r");
int addr [MAX_ADDR]; //定义一个空数组
if(!fp) return; //打开文件失败
//从文件中逐一读出每一联系人信息
while(fscanf(fp,"%s",addr)!=EOF)
{
p=(StuNode*)malloc(sizeof(StuNode));
if(p!=NULL)
{
if(1)
{
addr [p->stu.addr]++;
fscanf(fp,"%s",p->stu.addr);
}
}
//每一联系人加入到链表中
p->next=student;
student=p;
p=NULL;
}
fclose(fp); //关闭文件
BubbleSort(); //进行排序
}
void Teshu()
{
StuNode *p=student;
printf("****************************n");
while(p) //检查湖南籍贯学生是否存在
{
if(strcmp(p->stu.addr,"湖南")==0)
break;
p=p->next;
}
if(!p)
{
printf("** 没有该籍贯学生! **n");
printf("*******************************n");
}
else //待查找学生存在则输出信息
{
printf("****************************n");
printf("* 学生籍贯信息 *n");
printf("****************************n");
printf("$学 号 :%sn",p->stu.id);
printf("$姓 名 :%sn",p->stu.name);
printf("$身份证号码 :%sn",p->stu.shenfen);
printf("$出生日期:%sn",p->stu.birth);
printf("$籍 贯 :%sn",p->stu.addr);
printf("$手机号码:%sn",p->stu.tel);
printf("****************************n");
}
}
void Save()
{
StuNode *p=student;
FILE* fp;
fp = fopen("student.txt", "w");
fprintf(fp, "学号tt姓名tt身份证号码tt出生年月tt籍贯tt电话号码n");
while (p != NULL)
{
fprintf(fp, "%st", p->stu.id);
fprintf(fp, "%st", p->stu.name);
fprintf(fp, "t%s", p->stu.shenfen);
fprintf(fp, "t%s", p->stu.birth);
fprintf(fp, "t%s", p->stu.addr);
fprintf(fp, "tt%s", p->stu.tel);
fprintf(fp, "n");
p = p->next;
}
printf("保存成功,请到当前目录下的student.txt文件中查看");
fclose(fp);
}
void Exit()
{
StuNode *p=student;
while(p) //释放通讯录每一个结点内存空间
{
student=p->next;
free(p);
p=student;
}
}
void ReadFile()
{
StuNode *p;
char id[MAX_ID];
FILE *pf=fopen("student.txt","r"); //以读方式打开文件
if(!pf) return; //打开文件失败
//从文件中逐一读出每一联系人信息
while(fscanf(pf,"%s",id)!=EOF)
{
p=(StuNode*)malloc(sizeof(StuNode));
strcpy(p->stu.id,id);
fscanf(pf,"%s",p->stu.name);
fscanf(pf,"%s",p->stu.shenfen);
fscanf(pf,"%s",p->stu.birth);
fscanf(pf,"%s",p->stu.addr);
fscanf(pf,"%s",p->stu.tel);
//每一联系人加入到链表中
p->next=student;
student=p;
p=NULL;
}
fclose(pf); //关闭文件
}
void WriteFile()
{
StuNode *p=student;
FILE *pf=fopen("student.txt","w"); //以写方式打开文件
if(!pf) return; //打开文件失败
while(p) //将链表中的每一结点写入文件
{
fprintf(pf,"%s",p->stu.id);
fscanf(pf,"%s",p->stu.name);
fscanf(pf,"%s",p->stu.shenfen);
fscanf(pf,"%s",p->stu.birth);
fscanf(pf,"%s",p->stu.addr);
fscanf(pf,"%s",p->stu.tel);
p=p->next;
}
fclose(pf); //关闭文件
}
void BubbleSort()
{
int i ,count = 0, num;//count记录链表结点的个数,num进行内层循环,
NODE *p, *q, *tail;//创建三个指针,进行冒泡排序
p = L;
while(p->next != NULL)//计算出结点的个数
{
count++;//注释①
p = p->next;
}
for(i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样
{
num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样,
q = L->next;//令q指向第一个结点
p = q->next;//令p指向后一个结点
tail = L;//让tail始终指向q前一个结点,方便交换,也方便与进行下一步操作
while(num--)//内层循环 次数跟数组冒泡排序一样
{
if(q->data < p->data)//如果该结点的值小于于后一个结点,则交换
{
q->next = p->next;
p->next = q;
tail->next = p;
}
tail = tail->next;//注释②
q = tail->next;//注释②
p = q->next;//注释②
}
}
}
int FindStu(char* id)
{
StuNode *p=student;
while(p) //在链表中以学号方式查找某一联系人是否存在
{
if(strcmp(id,p->stu.id)==0)
return 1; //存在则返回1
p=p->next;
}
return 0; //不存在则返回0
}
int main()
{
ShowMenu();
}