C语言《学生综合管理系统》基于链表和文件操作

该系统是以工程为基础的,每个#include”head.h”后面请自己新建工程内源文件,程序有3个数据文件DataInformation.txt(学生信存储文件)&&student_UserInformation.txt(学生用户登录数据文件例:学号:140101密码123456)&&teacher_UserInformation.txt(教师信息数据文件例:用户名:admin 密码admin)
头文件的声明:
#include

include

include

include

struct student{
    char stu_major[15];     //专业
    int stu_class;          //班级
    int stu_ID;             //班级内ID
    char stu_name[20];
    int score_math,score_english,score_c;
    int score_ave;
    int ME;                 //Mutual evaluation(同学互评)
    int CE;                 //The counselor evaluation(辅导员评价)
    int TM_all;             //教师评价总分
    int ZH_score;           //综合总分
    struct student *next;
};

    //声明函数
    FILE *openfile(char *fileaddress,char *openmode);

    int  Login(void);//登录函数

    void Teacher_Main(void);//教师函数

    void Student_Main(int stu_ID,int stu_class);//学生函数

    student *NewLinkList(void);//新建链表

    void DisplayStudent(void);//展示全部学生信息

    void AddNewStudent();//新增学生信息

    student *FindStudent(int stu_ID,int stu_class);//查找学生

    void DeleteStudent(void);//删除学生信息并将删除后全部学生信息保存进文件

    student *Rank(struct student *head);//排序

    void Change(void);  //修改学生信息函数

    void ClassMate(int stu_ID,int stu_class);   //同学互评

    void ModifyPassword(int ID);//密码修改函数

下面是全部程序

#include"head.h"
void main(){
system("title 学生综合信息管理系统V1.0  —— 吴银制作");//设置标题
system("mode con cols=130 lines=75");//设置窗口大小

int size=sizeof(student);
int LoginResult=Login();
switch(LoginResult){
case -1:{//进入教师端
Teacher_Main();
break;
   }
case 0:{
   printf("账户,密码验证错误次数太多系统已退出!");
   break;
   }
default:{//进入学生端
int stu_ID,stu_class;
stu_class=LoginResult/100;
stu_ID=(LoginResult-stu_class*100);
Student_Main(stu_ID,stu_class);
break;
}
}
getchar();
getchar();
}


/*该函数用于系统登录,教师登录成功后返回1,学生登录成功后返回学号,
若多次密码验证后未成功登录则返回0。
*/

//分别是教师密码验证函数和学生密码验证函数,这两个函数均有返回值,
//若账户和密码通过验证均返回1,否则0
#include"head.h"
int teacher_user(char name[],char password[]);
int student_user(int stu_ID,int password);

//登录器主函数
int Login(){
printf("\t欢迎使用学生综合信息管理系统\n");
printf("   请选择登录类型...\n\tA.教师登录\t\t其他.学生登录\n");
char choice;
int result;//int型返回值,教师返回-1,学生返回学号,输入错误返回0
choice=getchar();
if(choice=='A'||choice=='a'){
char UserName[20],UserPassword[7];//定义密码和用户名
for(int i=1;i<=3;i++){
printf("请输入用户名:");
scanf("%s",UserName);
printf("请输入密码:");
scanf("%s",UserPassword);
printf("\n");
if(teacher_user(UserName,UserPassword)==1){//调用教师密码验证函数并判断返回值
printf("教师端登录成功...\n");
result=-1;//教师端返回-1
break;
}
else{
printf("用户名,密码错误。\n");
result=0;//登录错误返回0
}
}
return result;
}
else{
int UserName,Password;
for(int i=1;i<=3;i++){
printf("学号:");
scanf("%d",&UserName);
printf("密码:");
scanf("%d",&Password);
if(student_user(UserName,Password)==1){
printf("学生端登录成功.\n");
result=UserName;//学生端返回学号
break;
}else{
printf("用户名,密码错误。\n");
result=0;
}
}
} 
return result;
}
//教师密码验证器
int teacher_user(char name[],char password[]){
FILE *fp;
char UserName[20],UserPassword[7];
fp=openfile("teacher_UserInformation.txt","a+");
//遍历文件中存储的账户和密码,并验证是否通过参数传递过来的账户密码是否正确
while(1){
fscanf(fp,"%s%s",UserName,UserPassword);
if((strcmp(UserName,name)==0)&&(strcmp(UserPassword,password)==0)){
return 1;
break;
}
}
return 0;
}
//学生密码验证器
int student_user(int stu_ID,int password){
FILE *fp=openfile("student_UserInformation.txt","a+");
int UserName,UserPassword;
//遍历文件中存储的账户和密码,并验证是否通过参数传递过来的账户密码是否正确
while(!feof(fp)){//feof()是个陷阱函数,该函数会导致文件最后一条数据被多读取一次
fscanf(fp,"%d%d",&UserName,&UserPassword);
if((UserName==stu_ID)&&(password==UserPassword)){
return 1;
break;
}
}
return 0;
}

/*
学生信息新增函数,用于录入一个或多个学生信息并直接存入学生信息存储文件
*/
#include"head.h"

void AddNewStudent(){

char name[20],major[15];
int stu_class,stu_ID,count=0;

struct student *head,*ptr,*p,*temp;

head=NewLinkList();
ptr=head;
p=head->next;

temp=(struct student *)malloc(sizeof(student));  
temp->next=NULL;

while(NULL!=ptr->next)//遍历链表,找到链尾
{
ptr=ptr->next;
}

ptr->next = (struct student *)malloc(sizeof(student));              //默认在链表末追加添加信息  
ptr = ptr->next;  
ptr->next = NULL; 

for(int i=1;i<2;i++){

printf("请输入学生基本信息...\n专业\t班级\t学号\t姓名\n");
scanf("%s%d%d%s",major,&stu_class,&stu_ID,name);

//判断该学生是否存在
while(p!=NULL){
if(((strcmp(p->stu_major,major)==0)&&(p->stu_class==stu_class)&&(p->stu_ID==stu_ID)))
{

count++;
break;
}
p=p->next;
}
if(count!=0){printf("该学生已存在!\n"); break;}//若计数器不为0则说明该学生已经存在

printf("高数\t英语\tc语言\t 导员评分 教师评分\n");
scanf("%d%d%d%d%d",&temp->score_math,&temp->score_english,&temp->score_c,&temp->CE,&temp->TM_all);
temp->ME=0;

if(((0>=temp->score_math)||(temp->score_math>=100))||((0>=temp->score_english)||(temp->score_english>=100))||((0>=temp->score_c)||(temp->score_c>=100)))
{//判断输入的成绩是否合法(大于等于0&&小于等于100printf("成绩不能小于0或大于100!\n");
}else{

ptr->stu_class=stu_class;
ptr->stu_ID=stu_ID;
strcpy(ptr->stu_major,major);
strcpy(ptr->stu_name,name);

ptr->score_math=temp->score_math;
ptr->score_english=temp->score_english;
ptr->score_c=temp->score_c;
ptr->ME=temp->ME;
ptr->CE=temp->CE;
ptr->TM_all=temp->TM_all;
//通过前面输入的数据计算出该学生的平均分,和综合总分
ptr->score_ave=(temp->score_math+temp->score_english+temp->score_c)/3;
ptr->ZH_score=ptr->score_ave*7/10+(temp->CE+temp->ME+temp->TM_all)/10;

//将该学生的学号存储到学生用户文件中以供该学生登录学生端是进行密码验证
{
FILE *fp2=openfile("student_UserInformation.txt","a");
fprintf(fp2,"%d\t%d\n",(stu_class*100+stu_ID),123456);
}

head=head->next; 
head=Rank(head);//对新增学生信息后的链表按学号排序


/*将更改后的信息存储在文件中*/
FILE *fp=openfile("DataInformation.txt","w+");
ptr=head;  
while( ptr != NULL )  
   {  
      fprintf(fp,"%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,ptr->score_math,
ptr->score_english,ptr->score_c,ptr->score_ave,
ptr->ME,ptr->CE,ptr->TM_all,ptr->ZH_score);

    ptr = ptr->next;  
 }  
printf("新增学生成功!\n");
fclose(fp);
}
}
}

#include"head.h"
void Change(void){
struct student *head,*p,*ptr;
int stu_ID,stu_class;
printf("请输入您要修改学生的班级和学号:");
scanf("%d%d",&stu_class,&stu_ID);
head=NewLinkList();
p=head->next;
while(p!=NULL){
if((p->stu_ID==stu_ID)&&(p->stu_class==stu_class)){
printf("请输入%s基本信息...\n专业\t班级\t学号\t姓名\t高数\t英语\tc语言 导员评分 教师评分\n",p->stu_name);
printf("%s\t%d\t%d\t%s\t",p->stu_major,p->stu_class,p->stu_ID,p->stu_name);
scanf("%d%d%d%d%d",&p->score_math,&p->score_english,&p->score_c,&p->CE,&p->TM_all);

p->score_ave=(p->score_math+p->score_english+p->score_c)/3;
p->ZH_score=p->score_ave*7/10+(p->CE+p->ME+p->TM_all)/10;
break;
}else{
p=p->next;
}
}
head=head->next;
head=Rank(head);//对新增学生信息后的链表按学号排序

ptr=head;  
FILE *fp=openfile("DataInformation.txt","w+");
ptr=head;  
    while( ptr != NULL )  
    {  
 fprintf(fp,"%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,ptr->score_math,
ptr->score_english,ptr->score_c,ptr->score_ave,
ptr->ME,ptr->CE,ptr->TM_all,ptr->ZH_score);

        ptr = ptr->next;  
    }
fclose(fp);
}

//同学互评函数,可对全班同学评价,也可更加输入的学号进行单个学生评价
#include"head.h"
void ClassMate(int stu_ID,int stu_class)//函数参数是登录了学生端学生的学号和班级用于判断是否同班和,不对自己进行评价
{
struct student *head,*p,*ptr;
int ME=0,choice;

head=NewLinkList();//新建链表
p=head;
printf("\t对全班同学进行评价请输入0\n\t\t输入学号对评价某个同学进行评价\n请输入...");
scanf("%d",&choice);
switch(choice){
case 0://对全部学生评价
{
   printf("请输入您对同学的评价...\n");
printf("姓名\t学号\t同学互评成绩\n");
while(p!=NULL)
{
if(p->stu_class==stu_class)//查找是否一个班级
{
if(p->stu_ID!=stu_ID)
{
printf("%s\t%d",p->stu_name,p->stu_ID);//输出一个班级且不是本人的学生姓名和学号
scanf("%d",&ME);//输入评价
if(p->ME==0){//判断之前是否有人对学生进行评价若无则第一个评价直接是学生总评价
p->ME=ME+100;
p->ZH_score=p->score_ave*7/10+(p->CE+p->ME+p->TM_all)/10;
}else{//若之前同学互评不为0,则去前数和输入数的平均值
p->ME=((p->ME/100)*(p->ME-(p->ME/100)*100)+ME)/(p->ME/100+1)+((p->ME/100+1)*100);
p->ZH_score=p->score_ave*7/10+(p->CE+p->ME+p->TM_all)/10;
}
}
}
p=p->next;
}
break;
   } 
default:{//对某个学号的同学评价
int count=0;
while(p!=NULL){
if((p->stu_class==(choice/100))&&(p->stu_ID==(choice-(choice/100)*100)))
{
 printf("请输入您对同学的评价...\n");
 printf("姓名\t学号\t同学互评成绩\n");
 printf("%s\t%d",p->stu_name,p->stu_ID);
     scanf("%d",&ME);
 /*学生评价是取多人评价平均数,p->ME是储存的人数和之前的平均数信息后两位数值是之前所求得得平均数下次使用时*/
if(p->ME==0){
p->ME=ME+100;
p->ZH_score=p->score_ave*7/10+(p->CE+(p->ME-p->ME/100*100)+p->TM_all)/10;
count++;
}else{
p->ME=((p->ME/100)*(p->ME-(p->ME/100)*100)+ME)/(p->ME/100+1)+((p->ME/100+1)*100);
p->ZH_score=p->score_ave*7/10+(p->CE+(p->ME-p->ME/100*100)+p->TM_all)/10;
count++;//计数器用来记录是否有查找到学生,查找到学生计数器加一
}
} 
p=p->next;
}
if(count==0)printf("未找到该学生!");
break ;
}
}


/*将更改后的信息存储在文件中*/
FILE *fp=openfile("DataInformation.txt","w+");
ptr=head->next;  
    while( ptr != NULL )  
    {  
 fprintf(fp,"%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,ptr->score_math,
ptr->score_english,ptr->score_c,ptr->score_ave,
ptr->ME,ptr->CE,ptr->TM_all,ptr->ZH_score);

        ptr = ptr->next;  
    }  
fclose(fp);
}

//函数用于删除一条学生信息
#include"head.h"
void DeleteStudent(void){
struct student *head,*ptr1,*ptr2,*p;
head=NewLinkList();//新建链表

int stu_ID,stu_class;
printf("请输入您要删除的学生班级和学号:");
scanf("%d%d",&stu_class,&stu_ID);

//要被删除的为空节点
while(head!=NULL&&((head->stu_ID==stu_ID)&&(head->stu_class=stu_class)))
{
ptr2=head;
head=head->next;
free(ptr2);
}
if(head==NULL)
printf("链表为空!");
//要被删除的为非表头节点
ptr1=head;
ptr2=head->next;/*从表头的下一个结点搜索所有符合删除要求的结点*/
while(ptr2!=NULL)
{
if((ptr2->stu_ID==stu_ID)&&(ptr2->stu_class=stu_class))/*ptr2所指结点符合删除要求*/
{
ptr1->next=ptr2->next;
printf("已成功删除该学生信息!\n");
free(ptr2);
}else
ptr1=ptr2;/*ptr1后移一个结点*/
ptr2=ptr1->next;/*ptr2指向ptr1的后一个结点*/
}
ptr2=head;
head=head->next;//将链表表头后移一个结点
free(ptr2);
head=Rank(head);//调用排序函数对链表结点排序
FILE *fp=openfile("DataInformation.txt","w+");
p=head;
//将修改后的链表信息保存到文件
while(p!=NULL)
{
 fprintf(fp,"%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
 p->stu_major,p->stu_class,p->stu_ID,p->stu_name,p->score_math,
 p->score_english,p->score_c,p->score_ave,p->ME,p->CE,p->TM_all,p->ZH_score);
 p=p->next;
}
fclose(fp);
free(head);
}

/*
该函数用于根据用户选择按一定顺序对学生信息排序显示
*/
#include"head.h"
void all_student(void);//显示全部学生信息
void Choice_print(void);//按需显示学生信息
void DisplayStudent(void){
int choice;
printf("\t1.显示全部学生信息\n\t2.按成绩排序显示\n请输入您的选择...");
scanf("%d",&choice);
switch(choice){
case 1:{
all_student();
break;
   }
case 2:{
   Choice_print();
   break;
   }
default:{
printf("输入错误!\n");
}
}
} 
void all_student(void){
FILE *fp=openfile("DataInformation.txt","a+");
struct student *temp;
char major[20],name[15];

temp=(struct student *)malloc(sizeof(struct student));//给临时容器申请一个空间

fscanf(fp,"%s%d%d%s%d%d%d%d%d%d%d%d",//使用fscanf从文件中读取一行数据
major,&temp->stu_class,&temp->stu_ID,name,//在while外读取一次是为了使feof()能正常工作
&temp->score_math,&temp->score_english,&temp->score_c,//因为feof会在文件读取完了下一次读取时才返回1
&temp->score_ave,&temp->ME,&temp->CE,&temp->TM_all,&temp->ZH_score);
strcpy(temp->stu_major,major);
strcpy(temp->stu_name,name);
printf("专业\t班级\t学号\t姓名\t高数\t英语\tc语言 平均分 同学互评 导员评分 教师评分 综合得分\n");
while(!feof(fp)){
printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
temp->stu_major,temp->stu_class,temp->stu_ID,temp->stu_name,
temp->score_math,temp->score_english,temp->score_c,
temp->score_ave,(temp->ME-temp->ME/100*100),temp->CE,temp->TM_all,temp->ZH_score);

fscanf(fp,"%s%d%d%s%d%d%d%d%d%d%d%d",
major,&temp->stu_class,&temp->stu_ID,name,
&temp->score_math,&temp->score_english,&temp->score_c,
&temp->score_ave,&temp->ME,&temp->CE,&temp->TM_all,&temp->ZH_score);
strcpy(temp->stu_major,major);
strcpy(temp->stu_name,name);
}

}
void Choice_print(void){

struct student *head,*ptr,*qtr,*temp;
temp=(struct student *)malloc(sizeof(student));//定义空的链表节点来当做排序时临时容器,链表下一节点为空节点
temp->next=NULL;
int len=0;//链表长度 
int i,j;//ij循环次数控制参数  

head=NewLinkList();

ptr=head->next;  
while(ptr != NULL)             //测链表长度,不包括表头结点  
{  
ptr=ptr->next;  
len++;  
}  
ptr=head->next;//指针ptr用过之后记得回原位  

printf("\t1.根据高数排序\n\t2.根据英语排序\n\t3.根据c语言排序\n请输入您的选择...");
int choice;
scanf("%d",&choice);//获取用户选择
printf("序号\t专业\t班级\t学号\t姓名\t高数\t英语\tc语言\t平均分\t同学互评 导员评分 教师评分 综合得分\n");
switch(choice){
case 1:{
//冒泡排序算法开始
for( i=0;i<len;i++)  
  {  
qtr=head->next;           //每一次内循环之后,ptrqtr必然在最后两个节点上
       ptr=head->next->next;    //故在进行内循环之前,要重新复位ptrqtr
for( j=0;j<len-i-1;j++)  
   {  
  if(  (ptr->score_math > qtr->score_math)&&(ptr->stu_class==qtr->stu_class) )  
{  
 // 进行数据交换
                    strcpy(temp->stu_major,qtr->stu_major);
strcpy(temp->stu_name,qtr->stu_name);
temp->stu_ID=qtr->stu_ID;
temp->stu_class=qtr->stu_class;
temp->score_math=qtr->score_math;
temp->score_english=qtr->score_english;
temp->score_c=qtr->score_c;
temp->score_ave=qtr->score_ave;
temp->ME=qtr->ME;
temp->CE=qtr->CE;
temp->TM_all=qtr->TM_all;
temp->ZH_score=qtr->ZH_score;

strcpy(qtr->stu_major,ptr->stu_major);
strcpy(qtr->stu_name,ptr->stu_name);
qtr->stu_ID=ptr->stu_ID;
qtr->stu_class=ptr->stu_class;
qtr->score_math=ptr->score_math;
qtr->score_english=ptr->score_english;
qtr->score_c=ptr->score_c;
qtr->score_ave=ptr->score_ave;
qtr->ME=ptr->ME;
qtr->CE=ptr->CE;
qtr->TM_all=ptr->TM_all;
qtr->ZH_score=ptr->ZH_score;

strcpy(ptr->stu_major,temp->stu_major);
strcpy(ptr->stu_name,temp->stu_name);
ptr->stu_ID=temp->stu_ID;
ptr->stu_class=temp->stu_class;
ptr->score_math=temp->score_math;
ptr->score_english=temp->score_english;
ptr->score_c=temp->score_c;
ptr->score_ave=temp->score_ave;
ptr->ME=temp->ME;
ptr->CE=temp->CE;
ptr->TM_all=temp->TM_all;
ptr->ZH_score=temp->ZH_score;

                }  
                qtr = qtr->next;  
                ptr = ptr->next;  
            }  
        }  
ptr=head->next;  
int m=1;
//将获得的按一定顺序降序排列后的学生信息进行显示
    while(ptr!= NULL )  
    {   
if(ptr==NULL)break;
        printf(" %d\t%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
m,ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,
ptr->score_math,ptr->score_english,ptr->score_c,ptr->score_ave,
(ptr->ME-ptr->ME/100*100),ptr->CE,ptr->TM_all,ptr->ZH_score);
        ptr = ptr->next;  
m++;

    }
break;
   }
case 2:{
  //冒泡排序算法开始
for( i=0;i<len;i++)  
  {  
qtr=head->next;           //每一次内循环之后,ptrqtr必然在最后两个节点上
       ptr=head->next->next;    //故在进行内循环之前,要重新复位ptrqtr
for( j=0;j<len-i-1;j++)  
   {  
  if(  (ptr->score_english > qtr->score_english)&&(ptr->stu_class==qtr->stu_class) )  
{  
                    strcpy(temp->stu_major,qtr->stu_major);
strcpy(temp->stu_name,qtr->stu_name);
temp->stu_ID=qtr->stu_ID;
temp->stu_class=qtr->stu_class;
temp->score_math=qtr->score_math;
temp->score_english=qtr->score_english;
temp->score_c=qtr->score_c;
temp->score_ave=qtr->score_ave;
temp->ME=qtr->ME;
temp->CE=qtr->CE;
temp->TM_all=qtr->TM_all;
temp->ZH_score=qtr->ZH_score;

strcpy(qtr->stu_major,ptr->stu_major);
strcpy(qtr->stu_name,ptr->stu_name);
qtr->stu_ID=ptr->stu_ID;
qtr->stu_class=ptr->stu_class;
qtr->score_math=ptr->score_math;
qtr->score_english=ptr->score_english;
qtr->score_c=ptr->score_c;
qtr->score_ave=ptr->score_ave;
qtr->ME=ptr->ME;
qtr->CE=ptr->CE;
qtr->TM_all=ptr->TM_all;
qtr->ZH_score=ptr->ZH_score;

strcpy(ptr->stu_major,temp->stu_major);
strcpy(ptr->stu_name,temp->stu_name);
ptr->stu_ID=temp->stu_ID;
ptr->stu_class=temp->stu_class;
ptr->score_math=temp->score_math;
ptr->score_english=temp->score_english;
ptr->score_c=temp->score_c;
ptr->score_ave=temp->score_ave;
ptr->ME=temp->ME;
ptr->CE=temp->CE;
ptr->TM_all=temp->TM_all;
ptr->ZH_score=temp->ZH_score;

                }  
                qtr = qtr->next;  
                ptr = ptr->next;  
            }  
        }  
ptr=head->next;  
int m=1;
    while(ptr!= NULL )  
    {   
if(ptr==NULL)break;
        printf(" %d\t%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
m,ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,
ptr->score_math,ptr->score_english,ptr->score_c,ptr->score_ave,
(ptr->ME-ptr->ME/100*100),ptr->CE,ptr->TM_all,ptr->ZH_score);
        ptr = ptr->next;  
m++;

    }
break;
   }
case 3:{
       //冒泡排序算法开始
for( i=0;i<len;i++)  
  {  
qtr=head->next;           //每一次内循环之后,ptrqtr必然在最后两个节点上
       ptr=head->next->next;    //故在进行内循环之前,要重新复位ptrqtr
for( j=0;j<len-i-1;j++)  
   {  
  if(  (ptr->score_c> qtr->score_c)&&(ptr->stu_class==qtr->stu_class) )  
{  
                    strcpy(temp->stu_major,qtr->stu_major);
strcpy(temp->stu_name,qtr->stu_name);
temp->stu_ID=qtr->stu_ID;
temp->stu_class=qtr->stu_class;
temp->score_math=qtr->score_math;
temp->score_english=qtr->score_english;
temp->score_c=qtr->score_c;
temp->score_ave=qtr->score_ave;
temp->ME=qtr->ME;
temp->CE=qtr->CE;
temp->TM_all=qtr->TM_all;
temp->ZH_score=qtr->ZH_score;

strcpy(qtr->stu_major,ptr->stu_major);
strcpy(qtr->stu_name,ptr->stu_name);
qtr->stu_ID=ptr->stu_ID;
qtr->stu_class=ptr->stu_class;
qtr->score_math=ptr->score_math;
qtr->score_english=ptr->score_english;
qtr->score_c=ptr->score_c;
qtr->score_ave=ptr->score_ave;
qtr->ME=ptr->ME;
qtr->CE=ptr->CE;
qtr->TM_all=ptr->TM_all;
qtr->ZH_score=ptr->ZH_score;

strcpy(ptr->stu_major,temp->stu_major);
strcpy(ptr->stu_name,temp->stu_name);
ptr->stu_ID=temp->stu_ID;
ptr->stu_class=temp->stu_class;
ptr->score_math=temp->score_math;
ptr->score_english=temp->score_english;
ptr->score_c=temp->score_c;
ptr->score_ave=temp->score_ave;
ptr->ME=temp->ME;
ptr->CE=temp->CE;
ptr->TM_all=temp->TM_all;
ptr->ZH_score=temp->ZH_score;
                }  
                qtr = qtr->next;  
                ptr = ptr->next;  
            }  
        }  
ptr=head->next;  
int m=1;
    while(ptr!= NULL )  
    {   
if(ptr==NULL)break;
        printf(" %d\t%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n",
m,ptr->stu_major,ptr->stu_class,ptr->stu_ID,ptr->stu_name,
ptr->score_math,ptr->score_english,ptr->score_c,ptr->score_ave,
(ptr->ME-ptr->ME/100*100),ptr->CE,ptr->TM_all,ptr->ZH_score);
        ptr = ptr->next;  
m++;

    }
break;
   }
}
}

/*该函数是传入一个学生ID进行查找后返回该ID的结构体信息
  该函数可用于教师端学生信息查找,学生端个人信息查看
  该函数return找到的这个学生信息结构体的存储地址指针
*/
#include"head.h"
student *FindStudent(int stu_ID,int stu_class){
struct student *head,*p,*result=NULL;

head=NewLinkList();//调用新建链表函数,读取文件内容
p=head->next;//使用链表结点后移一个
while(p!=NULL)
{
if((p->stu_class==stu_class))//首先判断班级
{
if((p->stu_ID==stu_ID)){//相同班级后查找班级内学号以确定不会串班
result=p;//找到这个学生后将这个学生的信息存储地址赋值给返回值
result->next=NULL;//并将返回值的下一结点地址置为NULL
break;
}else{
p=p->next;//如果相同班级内没找到相同ID将链表结点后移一个继续下一次查找
}
}else{
p=p->next;//班级不同结点后移进行下一次循环查找
}
}
return result;//将找到的结点返回
}

//用户密码修改函数,若是教师函数参数固定传入为-1,学生修改密码的话传入学号为参数
#include"head.h"
void student(int stu_ID);
void teacher(void);

void ModifyPassword(int ID){
switch(ID){//判断是学生修改密码还是教师修改密码
case -1:{
teacher();
break;
}
default:{
student(ID);
break;
}
}
}

//学生修改密码
void student(int stu_ID){
struct StudentPassword{
int stu_ID,Password;
struct StudentPassword *next;
};

struct StudentPassword *head,*p;
int ID,Password;
FILE *fp=openfile("student_UserInformation.txt","a+");

head=(struct StudentPassword *)malloc(sizeof(struct StudentPassword));
p=head;//有头结点地址链表,使用链表时后移一个结点
p->next=NULL;

fscanf(fp,"%d%d",&ID,&Password);
while(!feof(fp)){
p->next=(struct StudentPassword *)malloc(sizeof(struct StudentPassword));
p=p->next;
p->next=NULL;

p->stu_ID=ID;
p->Password=Password;

fscanf(fp,"%d%d",&ID,&Password);
}
printf("请输入新密码:");
//将链表遍历找到该账号,并修改该账号密码
while(p!=NULL){
if(p->stu_ID==stu_ID){
scanf("%d",&Password);
if(p->Password==Password){
printf("新密码不能与原密码相同!\n");
printf("请重新输入密码:");
}else{
int Password2;
printf("请再次输入密码:");
scanf("%d",&Password2);//验证密码是否与第一次相同
if(Password==Password2){
printf("密码修改成功!");
p->Password=Password;
break;
}else{
printf("两次密码不一致!\n");
}
}
}
p=p->next;
}

fp=openfile("student_UserInformation.txt","w+");//将原文件删除并新建

//将修改后的教师用户保存
p=head->next;//指针p用过之后记得回原位 
while(p!=NULL){
fprintf(fp,"%d\t%d\n",p->stu_ID,p->Password);
p=p->next;
}
fclose(fp);

}


//教师修改密码
void teacher(void){

struct teacher{
char UserName[20],UserPassword[7];
struct teacher *next;
};
struct teacher *head,*p;
char UserName[20],Password[7];
FILE *fp=openfile("teacher_UserInformation.txt","a+");

head=(struct teacher *)malloc(sizeof(struct teacher));
p=head;
p->next=NULL;

fscanf(fp,"%s%s",UserName,Password);
while(!feof(fp)){
p->next=(struct teacher *)malloc(sizeof(struct teacher));
p=p->next;
p->next=NULL;

strcpy(p->UserName,UserName);//读取文件时字符不能直接读取到链表中
strcpy(p->UserPassword,Password);

fscanf(fp,"%s%s",UserName,Password);
}
fclose(fp);

p=head->next;//指针p用过之后记得回原位  

printf("请输入用户名:");
scanf("%s",UserName);
printf("请输入原密码:");
scanf("%s",Password);
while(p!=NULL){
if(strcmp(p->UserPassword,Password)==0){
char Password2[7];
printf("请输入新密码:");
scanf("%s",Password);
if(strcmp(p->UserPassword,Password)==0){
printf("新密码不能与原密码相同...\n");
}else{
printf("请再次输入新密码:");
scanf("%s",Password2);
if(strcmp(Password2,Password)==0){
strcpy(p->UserPassword,Password);
printf("密码修改已成功!\n");
break;
}else{
printf("两次密码不一样!\n");
}
}
}
p=p->next;
}

fp=openfile("teacher_UserInformation.txt","w+");//将原文件删除并新建

//将修改后的教师用户保存
p=head->next;//指针p用过之后记得回原位 
while(p!=NULL){
fprintf(fp,"%s\t%s\n",p->UserName,p->UserPassword);
p=p->next;
}
fclose(fp);

}

//新建链表函数
/*该函数用于新建一个链表并将存储学生信息的txt文件怎的学生信息读入链表中并return表头,
使用该函数是记得将使用的表头投结点后移一个结点,因为head是存储该链表的首地址并未存储学生信息*/
#include"head.h"
student *NewLinkList(void){

struct student *head,*p,*temp,*ptr;


char major[15];//定义临时存储变量
char name[20];

FILE *fp=openfile("DataInformation.txt","a+");//打开学生信息存储文件
head=(struct student *)malloc(sizeof(struct student));//头节点空间申请
temp=(struct student *)malloc(sizeof(struct student));//给临时容器申请一个空间
temp->next=NULL;//将临时存储器的下一结点赋值为NULL
p=head;//将链表投结点赋值给P
p->next=NULL;

fscanf(fp,"%s%d%d%s%d%d%d%d%d%d%d%d",//使用fscanf从文件中读取一行数据
major,&temp->stu_class,&temp->stu_ID,name,//在while外读取一次是为了使feof()能正常工作
&temp->score_math,&temp->score_english,&temp->score_c,//因为feof会在文件读取完了下一次读取时才返回1
&temp->score_ave,&temp->ME,&temp->CE,&temp->TM_all,&temp->ZH_score);
strcpy(temp->stu_major,major);
strcpy(temp->stu_name,name);

while(!feof(fp))//feof()判断文件是否读取到末尾了
{
p->next=(struct student *)malloc(sizeof(struct student));//为链表结点开辟存储空间
p=p->next;
p->next=NULL;

strcpy(p->stu_major,temp->stu_major);//讲读取到的内容转存到链表结点中
strcpy(p->stu_name,temp->stu_name);
p->stu_ID=temp->stu_ID;
p->stu_class=temp->stu_class;
p->score_math=temp->score_math;
p->score_english=temp->score_english;
p->score_c=temp->score_c;
p->score_ave=temp->score_ave;
p->ME=temp->ME;
p->CE=temp->CE;
p->TM_all=temp->TM_all;
p->ZH_score=temp->ZH_score;

fscanf(fp,"%s%d%d%s%d%d%d%d%d%d%d%d",//使用fscanf从文件中读取数据
major,&temp->stu_class,&temp->stu_ID,name,
&temp->score_math,&temp->score_english,&temp->score_c,
&temp->score_ave,&temp->ME,&temp->CE,&temp->TM_all,&temp->ZH_score);
strcpy(temp->stu_major,major);//读取文件时字符不能直接读取到链表中
strcpy(temp->stu_name,name);

}
fclose(fp);
return head;
}

#include"head.h"
FILE *openfile(char *fileaddress,char *openmode){
FILE *fp;
if((fp=fopen(fileaddress,openmode))==NULL){
printf("File open error!\n");
exit(0);
}
return(fp);
}


//排序函数:对链表根据学号升序排序
/*rank函数主要对学生信息根据学号排序,排序成功后返回,学生链表表头*/
#include"head.h"
student *Rank(struct student *x)
{
struct student *head,*ptr,*qtr,*temp;

temp=(struct student *)malloc(sizeof(student));//定义空的链表节点来当做排序时临时容器,链表下一节点为空节点
temp->next=NULL;//将下一结点地址置为NULL

int len=0;//链表长度 
int i,j;//ij循环次数控制参数  

head=x;//将hedd指向参数中传递过来的链表表头地址

ptr=head->next;  
    while(ptr != NULL)             //测链表长度,不包括表头结点  
    {  
        ptr=ptr->next;  
        len++;  
    }  
//冒泡排序算法开始
for( i=0;i<len;i++)  
        {  
qtr=head->next;           //每一次内循环之后,ptrqtr必然在最后两个节点上dd
            ptr=head->next->next;    //故在进行内循环之前,要重新复位ptrqtr
            for( j=0;j<len-i-1;j++)  
            {  
if(qtr->stu_ID>ptr->stu_ID){//判断学号后,数据交换
strcpy(temp->stu_major,qtr->stu_major);
strcpy(temp->stu_name,qtr->stu_name);
temp->stu_ID=qtr->stu_ID;
temp->stu_class=qtr->stu_class;
temp->score_math=qtr->score_math;
temp->score_english=qtr->score_english;
temp->score_c=qtr->score_c;
temp->score_ave=qtr->score_ave;
temp->ME=qtr->ME;
temp->CE=qtr->CE;
temp->TM_all=qtr->TM_all;
temp->ZH_score=qtr->ZH_score;

strcpy(qtr->stu_major,ptr->stu_major);
strcpy(qtr->stu_name,ptr->stu_name);
qtr->stu_ID=ptr->stu_ID;
qtr->stu_class=ptr->stu_class;
qtr->score_math=ptr->score_math;
qtr->score_english=ptr->score_english;
qtr->score_c=ptr->score_c;
qtr->score_ave=ptr->score_ave;
qtr->ME=ptr->ME;
qtr->CE=ptr->CE;
qtr->TM_all=ptr->TM_all;
qtr->ZH_score=ptr->ZH_score;

strcpy(ptr->stu_major,temp->stu_major);
strcpy(ptr->stu_name,temp->stu_name);
ptr->stu_ID=temp->stu_ID;
ptr->stu_class=temp->stu_class;
ptr->score_math=temp->score_math;
ptr->score_english=temp->score_english;
ptr->score_c=temp->score_c;
ptr->score_ave=temp->score_ave;
ptr->ME=temp->ME;
ptr->CE=temp->CE;
ptr->TM_all=temp->TM_all;
ptr->ZH_score=temp->ZH_score;
}
                qtr = qtr->next;  //内循环每循环一次环结点后移一个
                ptr = ptr->next;  
            }  
        }  
return head;
}

/*学生端主函数,用于对学生端的各项需求处理
*/
#include"head.h"
void Student_Main(int stu_ID,int stu_class){
int choice;
while(1){
//system("cls");

printf("\n\n  欢迎使用学生成绩管理系统_学生端\n");
printf("\t***********************************\n");
printf("\t | 1.查看个人信息\t\t |\n");
printf("\t | 2.修改账户密码\t\t |\n");
printf("\t | 3.同学互评    \t\t |\n");
printf("\t | 0.退出系统    \t\t |\n");
printf("\t***********************************\n");
printf("\t    请输入您的选择...");

scanf("%d",&choice);
if(choice==0) {
printf("感谢您的使用,系统已退出!再见!");
break;
}
switch(choice){
case 1:{
system("cls");
struct student *p;
    printf("专业\t班级\t学号\t姓名\t高数\t英语\tc语言\t平均分\t同学互评 导员评分 教师评分 综合得分\n");
p=FindStudent(stu_ID,stu_class);
printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t %d\t%d\t  %d\t   %d\n",
p->stu_major,p->stu_class,p->stu_ID,p->stu_name,p->score_math,
p->score_english,p->score_c,p->score_ave,(p->ME-p->ME/100*100),
p->CE,p->TM_all,p->ZH_score);
break;
   }
case 2:{
system("cls");
ModifyPassword((stu_class*100+stu_ID));//修改密码
break;
   }
case 3:{
system("cls");
   ClassMate(stu_ID,stu_class);//同学互评
   break;
   }
}
}
}

/*
教师端主函数,用于对教师端各项需求进行处理,无参数,无返回值
*/
#include"head.h"
void Teacher_Main(void){
int choice;

while(1){
//system("cls");

printf("欢迎使用学生成绩管理系统_教师端\n");
printf("\t***********************************\n");
printf("\t | 1.新增学生信息\t\t |\n");
printf("\t | 2.修改学生信息\t\t |\n");
printf("\t | 3.删除学生信息\t\t |\n");
printf("\t | 4.查找学生信息\t\t |\n");
printf("\t | 5.查看学生信息\t\t |\n");
printf("\t | 6.修改个人密码\t\t |\n");
printf("\t | 0.退出系统    \t\t |\n");
printf("\t***********************************\n");
printf("\t    请输入您的选择...");


scanf("%d",&choice);
if(choice==0) { printf("感谢您的使用,系统已退出!再见!");break;}

switch(choice){
case 1:{
system("cls");
AddNewStudent();
break;
   }
case 2:{
system("cls");
   Change();
   break;
   }

case 3:{
system("cls");
DeleteStudent();
break;
   }
case 4:{
system("cls");
int stu_ID,stu_class;
struct student *p;
printf("请输入您要查找的班级和学号:");
scanf("%d%d",&stu_class,&stu_ID);

p=FindStudent(stu_ID,stu_class);//调用函数查找学生
if(p==NULL){printf("未找到该学生!\n");break;}//没找到

printf("专业\t班级\t学号\t姓名\t高数\t英语\tc语言\t平均分\t同学互评 导员评分 教师评分 综合得分\n");
printf("%s\t%d\t%d\t%s\t%d\t%d\t%d\t%d\t %d\t%d\t  %d\t   %d\n",
p->stu_major,p->stu_class,p->stu_ID,p->stu_name,p->score_math,
p->score_english,p->score_c,p->score_ave,(p->ME-p->ME/100)*100,p->CE,p->TM_all,p->ZH_score);
break;
   }
case 5:{
system("cls");
DisplayStudent();
break;
   }
case 6:{
system("cls");
ModifyPassword(-1);
break;
   }
}

}
}
  • 4
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值