学生信息管理系统

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37806112/article/details/81529830

需求分析:

           1.分权限:学生和老师

           2.学生可以查询成绩,查看自己的单科排名,查看全部学生的信息

           3.学生不可以添加,修改,删除自己的成绩,只有老师可以,老师拥有所有权限。

           4.可以按照科目分数段查询

           5.对一些的信息进行格式处理,如编号为四位,且不能重复,姓名为字符,不能超过20个字符等等。

附data的数据格式:

0002  wd  chinese   89.000000  english   78.000000  math  89.000000 f
0001  ww  chinese   89.000000  english   98.000000  math  86.000000 f
0005  ty  chinese   78.000000  english   98.000000  math  86.000000 m
1008  po  chinese   98.000000  english   16.000000  math  48.000000 m
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//链表结点结构体声明
typedef struct subjects
{
	char name[20];
	float score;
}sub;

typedef struct student
{
	int num;
	char name[20];
	sub  subject[3];
	char sex[4];
	struct student* next;
}stu, *pstu;
#define SIZE sizeof(stu)

int number;
//函数申明
pstu LoadInfo();
void PrintMenu();
pstu AddStu(pstu);
pstu DeleStu(pstu);
pstu RwrStu(pstu);
void FindStu(pstu, int);
void Count(pstu, char *, float, float);
void Rank(pstu, char *);
void SaveQuit(pstu);
void printNode(pstu head);
void Rank_Node(pstu *head);
void printNode2(pstu head);
int login();
#include"student.h"

//加载data数据 ,文件操作
pstu LoadInfo()
{
	int   num;
	char name[20];
	char sub1[20];
	char sub2[20];
	char sub3[20];
	float score1;
	float score2;
	float score3;
    char sex[4];
	char filename[] = "data.txt";  //文件名,此处为简化编程,采用固定地址名称,未作输入
	FILE *fp;
	pstu head, ptr,tmp;

	//创建带表头结点的空单链表head,用来存放载入信息
	head=calloc(1,SIZE);
	ptr = head;
	ptr->next = NULL;

	//加载data文件,存入head链表
	if ((fp = fopen(filename, "r"))==NULL) 			//判断文件是否存在及可读
	{
		printf("error!");
		exit(0);
	}
    tmp = (pstu)calloc(1,SIZE);
	int iRet;
	//%[^|]|%[^|]|%d|%d|\n
	//while(!feof(fp))
	
	while(fscanf(fp, "%d  %s  %s  %f  %s  %f  %s  %f %s\n",&num, name,sub1, &score1, sub2, &score2, sub3, &score3,sex)!=EOF)//读取一行,采用格式化读取,避免了其他各种读取方法的数据处理问题
	{
		
		tmp->num = num;
		strcpy(tmp->name, name);
		strcpy(tmp->subject[0].name, sub1);
		tmp->subject[0].score = score1;
		strcpy(tmp->subject[1].name, sub2);
		tmp->subject[1].score = score2;
		strcpy(tmp->subject[2].name, sub3);
		tmp->subject[2].score = score3;
        strcpy(tmp->sex,sex);
		
		ptr->next=tmp;
		ptr = tmp;
		tmp = (pstu)calloc(1,SIZE);
		
	}
    free(tmp);
	fclose(fp);                     					//关闭文件,已得到保存data信息的链表head

	return head;
}

//打印主菜单
void PrintMenu()
{
	if(number==0)
	{
	system("clear");
	printf("\t\t\t\t\t\t***************************************\n");
	printf("\t\t\t\t\t\t             学生信息管理系统          \n");
	printf("\t\t\t\t\t\t***************************************\n");
	putchar('\n');
	printf("\t\t\t\t\t\t\t\t  菜单\n\n");
	printf("\t\t\t\t\t\t 1、信息管理\t\t 2、信息查询\n\n");
	printf("\t\t\t\t\t\t 3、成绩统计\t\t 4、成绩排序\n\n");
	printf("\t\t\t\t\t\t 5、保存退出\t\t 6、全部打印\n\n");
	printf("\t\t\t\t\t\t***************************************\n\n");
	}else
	{
	system("clear");
	printf("\t\t\t\t\t\t***************************************\n");
	printf("\t\t\t\t\t\t             学生信息管理系统          \n");
	printf("\t\t\t\t\t\t***************************************\n");
	putchar('\n');
	printf("\t\t\t\t\t\t\t\t  菜单\n\n");
	printf("\t\t\t\t\t\t 2、信息查询\t\t 3、成绩统计\n\n");
	printf("\t\t\t\t\t\t 4、成绩排序\t\t 5、保存退出\n\n");
	printf("\t\t\t\t\t\t 6、全部打印\n\n");
	printf("\t\t\t\t\t\t***************************************\n\n");	
	}
	
}

//添加学生
pstu AddStu(pstu x)
{
	char namestu[20],sex[4];
	char *p;
	char subname1[20], subname2[20], subname3[20];
	pstu head, ptr1,ptr;
    pstu tmp=calloc(1,SIZE);
	head = x;
	ptr = head;
	ptr1=head;
	tmp->next=NULL;
	printf("\t\t\t\t\t\t请输入添加学生的信息:\n");

	printf("\t\t\t\t\t\t请输入添加学生的学号:");
	int num1;
	scanf("%d",&num1);
	getchar();
    while (ptr1 != NULL)
	{
		if (ptr1->num == num1)
		{
		  printf("\t\t\t\t\t\t编号重复\n");
		  return head;
		}	
		ptr1=ptr1->next;
	}
	tmp->num=num1;
	printf("\t\t\t\t\t\t请输入添加学生的姓名:");
	scanf("%s", namestu);
	getchar();
	if(strlen(namestu)>9)
	{
		printf("\t\t\t\t\t\t长度不能超过9\n");
		return head;
	}
	strcpy(tmp->name, namestu);

	strcpy(tmp->subject[0].name, "chinese");
    
	float score1;
	printf("\t\t\t\t\t\t请输入添加学生的语文成绩:");
	scanf("%f", &score1);
	getchar();
    if(score1>100 || score1<0)
	{
		printf("\t\t\t\t\t\t输入的成绩在0~100之间\n");
		return head;
	}
	tmp->subject[0].score=score1;
	/*
	printf("\t\t\t\t\t\t请输入添加学生的科目2名称:");
	scanf("%s", subname2);
	getchar();
	p = subname2;
	*/
	strcpy(tmp->subject[1].name, "english");

	printf("\t\t\t\t\t\t请输入添加学生的英语成绩:");
	scanf("%f", &tmp->subject[1].score);
	getchar();
    
	strcpy(tmp->subject[2].name, "math");
	
	printf("\t\t\t\t\t\t请输入添加学生的数学成绩:");
	scanf("%f", &tmp->subject[2].score);
	getchar();
	
	printf("\t\t\t\t\t\t请输入添加学生的性别:");
	scanf("%s", sex);
	getchar();
	if(strcmp(sex,"f")==0||strcmp(sex,"m")==0)
	{
		strcpy(tmp->sex,sex);
	}
	else{
		printf("\t\t\t\t\t\t输入格式错误,f表示女 m表示男\n");
		return head;
	}
	
	while (NULL != ptr->next)					//遍历链表,找到链尾结点
	{
		ptr = ptr->next;
	}
    
	ptr->next = tmp;				//默认在链表末追加添加信息

	putchar('\n');
	return head;
}

//删除学生
pstu DeleStu(pstu x)
{
	int num;
	pstu head, ptr, qtr;

	head = x;
	ptr = head->next;
	qtr = head;

	printf("\t\t\t\t\t\t请输入要删除的学生的学号:");
	scanf("%d", &num);
	getchar();

	while (ptr != NULL)
	{
		if (ptr->num != num)				//遍历查找链表结点,未找到跳过该结点
		{
			ptr = ptr->next;
			qtr = qtr->next;
		}
		else						//找到则删除结点
		{
			ptr = ptr->next;
			qtr->next = ptr;
			break;
		}
	}

	printf("\t\t\t\t\t\t该学生信息已删除!\n\n");
	return head;
}

//修改学生信息
pstu RwrStu(pstu x)
{
	char namestu[20],sex[4];
	char *p;
	int num;
	int j=0;
	pstu head, ptr;

	head = x;
	ptr = head->next;

	printf("\n\t\t\t\t\t\t请输入要修改的学生的学号:");
	scanf("%d", &num);
	getchar();

	while (ptr != NULL)
	{
		if (ptr->num == num)
		{
			
			printf("\t\t\t\t\t\t1.修改学生的姓名 \t2.修改学生的语文成绩\n");
			printf("\t\t\t\t\t\t3.修改学生的英语成绩 \t4.修改学生的数学成绩\n");
			printf("\t\t\t\t\t\t5.修改学生的性别 \t6.退出\n");
			printf("\t\t\t\t\t\t已找到该学生信息,请选择修改项目:");
			scanf("%d",&j);
			switch(j)
			{
			   case 1:
			     printf("\t\t\t\t\t\t请输入修改学生的姓名:");
			     scanf("%s", namestu);
			     getchar();
			     p = namestu;
			     strcpy(ptr->name, p);
			   break;
			   
			   case 2:
			    printf("\t\t\t\t\t\t请输入修改学生的语文成绩:");
	            scanf("%f", &ptr->subject[0].score);
			   break;
				
			   case 3:
				printf("\t\t\t\t\t\t请输入修改学生英语成绩:");
			    scanf("%f", &ptr->subject[1].score);
			   break;
			   
			   case 4:
			     printf("\t\t\t\t\t\t请输入修改学生的数学成绩:");
			     scanf("%f", &ptr->subject[2].score);
			   break;
			   
			   case 5:
			     printf("\t\t\t\t\t\t请输入修改学生的性别:");
			     scanf("%s", sex);
			     getchar();
			     if(strcmp(sex,"f")==0||strcmp(sex,"m")==0)
	             {
		           strcpy(ptr->sex,sex);
	             }
	             else
			    {
		           printf("\t\t\t\t\t\t输入格式错误,f表示女 m表示男\n"); 
	            }
			     break;
			   case 6:
				 break;
			}
		    return head;
		}
		else
		{
			ptr = ptr->next;
		}
	}
    printf("\t\t\t\t\t\t该学生不存在\n");
	return head;
}

//查找学生,参数为链表指针,和学生学号
void FindStu(pstu x, int y)
{
	pstu head, ptr;

	head = x;
	ptr = head->next;

	while (ptr != NULL)
	{
		if (ptr->num == y)		//因主函数中为节省空间,学号输入采用char数据,故强行准换
		{
			printf("\t\t\t\t\t\t已找到该学生信息!\n\t\t\t\t\t\t如下:");
			printf("%04d  %s  %s  %5.2f  %s  %5.2f  %s  %5.2f\n",
				ptr->num, ptr->name, ptr->subject[0].name, ptr->subject[0].score, ptr->subject[1].name, ptr->subject[1].score, ptr->subject[2].name, ptr->subject[2].score);			break;			//注意此处找到并输出信息后要手动退出循环
		}
		else
		{
			ptr = ptr->next;
		}
	}
	if (ptr == NULL)				//查询成功检测,while循环中若找到,则ptr停留在当前学生的结点上
	{
		printf("\t\t\t\t\t\t未能找到该学生信息!\n");
	}
}


//统计科目分数区间段的学生,参数为链表指针,科目名称,分数区间上下限
//同理,参数的录入应放入子函数,简化结构和编程
void Count(pstu x, char *y, float q, float p)
{
	pstu head, ptr;
	char name[20];
	char flag = 0;       			//手动设置的查找结果flag

	head = x;
	ptr = head->next;
	strcpy(name, y);

	//printf("%s %5.2f %5.2f\n",name,q,p); 	//检测输入参数的传递,调试程序用
	while (ptr != NULL)			//开始查找统计,科目查找用strcmp函数比较科目字符串,返回值0为字符串相等
	{															//此处while循环体中,重复的查找步骤太多,应设置科目匹配flag,参照rank()函数
		if (strcmp(name, ptr->subject[0].name) == 0)	 //通过flag将科目确认放在while之外,循环体内只做分数区间的扫描和输出
		{
			if (q <= ptr->subject[0].score && ptr->subject[0].score <= p)
			{
				printf("\t\t\t\t\t\t%04d\t%s\t%s\t%.2f\n\n", ptr->num, ptr->name, ptr->subject[0].name, ptr->subject[0].score);
				flag++;
			}
		}
		if (strcmp(name, ptr->subject[1].name) == 0)
		{
			if (q <= ptr->subject[1].score && ptr->subject[1].score <= p)
			{
				printf("\t\t\t\t\t\t%04d\t%s\t%s\t%.2f\n\n", ptr->num, ptr->name, ptr->subject[1].name, ptr->subject[1].score);
				flag++;
			}
		}
		if (strcmp(name, ptr->subject[2].name) == 0)
		{
			if (q <= ptr->subject[2].score && ptr->subject[2].score <= p)
			{
				printf("\t\t\t\t\t\t%04d\t%s\t%s\t%.2f\n\n", ptr->num, ptr->name, ptr->subject[2].name, ptr->subject[2].score);
				flag++;
			}
		}

		ptr = ptr->next;
	}

	if (flag == 0)
	{
		printf("\t\t\t\t\t\t未能找到该课程该区间分数段的学生!\n\n");
	}
}


//学科成绩排名,采用交换数据的方法,参数为链表指针,科目名称
//同理参数问题
//链表排序问题,此处用交换结点数据方法,还有其他多种排序方法
void Rank(pstu x, char *y)
{
	pstu head, ptr, qtr;
	char name[20];
	char len = 0;
	char flag = 0;    				//简化算法,设置科目查找结果判断值,flag=0表示科目输入为未知科目,不存在
	int i = 0;													//i、j循环次数控制参数
	int j = 0;
	char temp_name[20],temp_sex[4];			//数据交换时的暂存信息变量
	float temp0, temp1, temp2;
	int temp_num;

	strcpy(name, y);
	head = x;

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


	//开始查找科目
	if (strcmp(name, ptr->subject[0].name) == 0)	flag = 1;
	if (strcmp(name, ptr->subject[1].name) == 0)	flag = 2;
	if (strcmp(name, ptr->subject[2].name) == 0)	flag = 3;
	if (flag == 0)
	{
		printf("\t\t\t\t\t\t未找到该科目!\n\n");
		return;
	}
	//开始排序,冒泡法比较各结点数据
	//此处3个并列的if用switch case更清晰结构
	if (flag == 1)
	{
		for (i = 0; i<len; i++)
		{
			ptr = head->next->next;	//每一次内循环之后,ptr、qtr必然在最后两个节点上
			qtr = head->next;		//故在进行内循环之前,要重新复位ptr、qtr
			for (j = 0; j<len - i - 1; j++)
			{
				if (qtr->subject[0].score < ptr->subject[0].score)
				{
					temp_num = qtr->num;	//交换数据,因数据格式(科目顺序)明确规定,故不再做科目名称的替换
					strcpy(temp_name, qtr->name);
					temp0 = qtr->subject[0].score;
					temp1 = qtr->subject[1].score;
					temp2 = qtr->subject[2].score;
                    strcpy(temp_sex, qtr->sex);
					
					qtr->num = ptr->num;
					strcpy(qtr->name, ptr->name);
					qtr->subject[0].score = ptr->subject[0].score;
					qtr->subject[1].score = ptr->subject[1].score;
					qtr->subject[2].score = ptr->subject[2].score;
					strcpy(qtr->sex, ptr->sex);

					ptr->num = temp_num;
					strcpy(ptr->name, temp_name);
					ptr->subject[0].score = temp0;
					ptr->subject[1].score = temp1;
					ptr->subject[2].score = temp2;
					strcpy(ptr->sex, temp_sex);
					
				}
				qtr = qtr->next;
				ptr = ptr->next;
			}
		}
	}

	if (flag == 2)
	{
		for (i = 0; i<len; i++)
		{
			ptr = head->next->next;
			qtr = head->next;
			for (j = 0; j<len - i - 1; j++)
			{
				if (qtr->subject[1].score < ptr->subject[1].score)
				{
					temp_num = qtr->num;
					strcpy(temp_name, qtr->name);
					temp0 = qtr->subject[0].score;
					temp1 = qtr->subject[1].score;
					temp2 = qtr->subject[2].score;
                    strcpy(temp_sex, qtr->sex);
					
					qtr->num = ptr->num;
					strcpy(qtr->name, ptr->name);
					qtr->subject[0].score = ptr->subject[0].score;
					qtr->subject[1].score = ptr->subject[1].score;
					qtr->subject[2].score = ptr->subject[2].score;
                    strcpy(qtr->sex, ptr->sex);
					
					ptr->num = temp_num;
					strcpy(ptr->name, temp_name);
					ptr->subject[0].score = temp0;
					ptr->subject[1].score = temp1;
					ptr->subject[2].score = temp2;
					strcpy(ptr->sex, temp_sex);
				}
				qtr = qtr->next;
				ptr = ptr->next;
			}
		}
	}

	if (flag == 3)
	{
		for (i = 0; i<len; i++)
		{
			ptr = head->next->next;
			qtr = head->next;
			for (j = 0; j<len - i - 1; j++)
			{
				if (qtr->subject[2].score < ptr->subject[2].score)
				{
					temp_num = qtr->num;
					strcpy(temp_name, qtr->name);
					temp0 = qtr->subject[0].score;
					temp1 = qtr->subject[1].score;
					temp2 = qtr->subject[2].score;
                    strcpy(temp_sex, qtr->sex);
					
					qtr->num = ptr->num;
					strcpy(qtr->name, ptr->name);
					qtr->subject[0].score = ptr->subject[0].score;
					qtr->subject[1].score = ptr->subject[1].score;
					qtr->subject[2].score = ptr->subject[2].score;
					strcpy(qtr->sex, ptr->sex);

					ptr->num = temp_num;
					strcpy(ptr->name, temp_name);
					ptr->subject[0].score = temp0;
					ptr->subject[1].score = temp1;
					ptr->subject[2].score = temp2;
					strcpy(ptr->sex, temp_sex);
				}
				qtr = qtr->next;
				ptr = ptr->next;
			}
		}
	}

	//输出排序过后的链表
	printNode(head);
}
int insertNode(pstu *newHead,pstu newNode)
{
	pstu q=*newHead;
	pstu p=*newHead; 
	//测试的是语文成绩
	while(p!=NULL)
	{
		if(p->subject[0].score > newNode->subject[0].score)
		{
            newNode->next=p;
			if(p==*newHead){
	
				
				*newHead=newNode;
			}
			else
			{
				q->next=newNode; 
			}
			return 0;	
		}
		q=p;
		p=q->next;	
	}
	//如果是空链表
	if(*newHead==NULL)
	{
		*newHead=newNode;
	}
	else
	{
		q->next=newNode;
		newNode->next=NULL;
	}	
}
//插入法排序
void Rank_Node(pstu *head)
{
	pstu newHead=NULL;
	//要排除第一个头结点
	pstu p=(*head)->next;
	*head=(*head)->next;
	while(p!=NULL)
	{
		*head=(*head)->next;
		p->next=NULL;
		
		insertNode(&newHead,p);	
		p=*head;		
	}
	//切记一定要加
	*head=newHead;
	
}

//保存文件并退出,文件操作
void SaveQuit(pstu head)
{
	pstu ptr;
	FILE *fp;
	char filename[] = "data.txt";
    ptr=head;
	ptr=ptr->next;
	if (NULL == (fp = fopen(filename, "w"))) 			//判断文件是否存在及可读
	{
		printf("error!");
		exit(0);
	}

	while (ptr != NULL)						//遍历链表结点,按data约定格式输出数据
	{    
		//%03d  %s  %s  %10f  %s  %10f  %s  %5f\n
		fprintf(fp, "%04d  %s  %s  %10f  %s  %10f  %s  %5f %s\n",ptr->num, ptr->name, ptr->subject[0].name, ptr->subject[0].score,ptr->subject[1].name, ptr->subject[1].score,ptr->subject[2].name, ptr->subject[2].score,ptr->sex);
		ptr = ptr->next;
	}

	fclose(fp);
}
//全部输出
void printNode(pstu head)
{   
    pstu ptr=head;
	pstu p=ptr->next;
	printf("\t\t\t\t\t学号  姓名 语文    成绩    英语    成绩   数学  成绩 性别\n ");
	while(p!=NULL)
	{
		printf("\t\t\t\t\t%04d  %s  %s  %5.2f  %s  %5.2f  %s  %5.2f %s\n",\
        p->num, p->name, p->subject[0].name, p->subject[0].score, p->subject[1].name, p->subject[1].score, p->subject[2].name, p->subject[2].score,p->sex);	
		
		p=p->next;
	}
}
void printNode2(pstu head)
{   
    pstu ptr=head;
	pstu p=ptr;
	printf("\t\t\t\t\t学号  姓名 语文    成绩    英语    成绩   数学  成绩 性别\n ");
	while(p!=NULL)
	{
		printf("\t\t\t\t\t%04d  %s  %s  %5.2f  %s  %5.2f  %s  %5.2f %s\n",\
        p->num, p->name, p->subject[0].name, p->subject[0].score, p->subject[1].name, p->subject[1].score, p->subject[2].name, p->subject[2].score,p->sex);	
		
		p=p->next;
	}
}

int login()
{
	system("clear");
	int i = 3,j;
    char ch[] = { "123456" };
    char input[20] = { 0 };
	
	printf("\t\t\t\t\t\t***************************************\n\n");
	printf("\t\t\t\t\t\t*             学生信息管理系统        *\n\n");
	printf("\t\t\t\t\t\t***************************************\n\n");
	printf("\t\t\t\t\t\t*\t1、学生\t\t2、老师\t      *        \n\n");
	printf("\t\t\t\t\t\t***************************************\n\n");
	printf("\t\t\t\t\t\t请选择您的身份:");
	scanf("%d",&j);
	
	 if (1 == j) 
		{         	
	       number=1;
		}
		else if (2 == j)
		{
		   number=0;
		}else
		{
			return -1;
		}
        			
    while (i)
    {
        printf("\t\t\t\t\t\t请输入你的登录密码:");
        scanf("%s", input);
        if (!strcmp(ch, input))
        {
            return 0;
        }
        else
        {
            i--;
            printf("\t\t\t\t\t\t输入有误,剩余输入次数为%d\n",i);

        }
    }
    if (i == 0)
    {
        return -1;
    }
    return 0;
}
#include "student.h"

//主函数
int main()
{
	float score1, score2;
	int n, j;
	char subname[20],password[20];
	pstu head, ptr;
    //Init();
	//printf("\033[40;37m\033[5m");
	
	head = LoadInfo();
	//测试
	//printNode(head);
	//创建菜单,进入选择循环
	if(-1==login())
	{
		printf("\t\t\t\t\t\t登录失败,退出:");
		return 0;
	}
	while (1)
	{
		PrintMenu();
		printf("\t\t\t\t\t\t请输入您的选择编号:");
		scanf("%d", &n);
		getchar();   					//接收上次输入选择后的回车输入,不致影响下一次输入
		switch (n)
		{	
		case 1:
		{
			      if(number==0)
				  {
				  //信息管理
				  system("clear");    			//清屏
				  j = 0;
				  while (4 != j)		   	//循环进入子菜单选择
				  {
						  printf("\t\t\t\t\t\t欢迎进入信息管理版块!\n\n");
						  printf("\t\t\t\t\t\t1、添加学生\n");
						  printf("\t\t\t\t\t\t2、删除学生\n");
						  printf("\t\t\t\t\t\t3、修改学生信息\n");
						  printf("\t\t\t\t\t\t4、返回\n");
						  printf("\t\t\t\t\t\t请输入您的选择编号:");
						  scanf("%d", &j);
						  getchar();
						  
						  if (1 == j) 
						  {           head = AddStu(head);		//添加学
						  }
						  else if (2 == j) head = DeleStu(head);		//删除学生
						  else if (3 == j) head = RwrStu(head);          //修改重写学生信息  						
						  else if (4 == j);
						  else printf("\t\t\t\t\t\t输入有误,请重新输入!\n");
					  
				  }
				  printf("\t\t\t\t\t\t请输入回车键返回主菜单!\n");     //此处本意按任意键返回,但是任意键的话,需要按键A,再按回车确定
				  getchar();			//则会连续收到两个按键,造成错误读入,可以改进scanf接收字符串,
				  system("clear");	
				  //以下所有getchar()、system("clear")同理
				  }
				  else{
					   printf("\t\t\t\t\t\t你无权访问\n\n");
				  }
				  break;
		}
		
		case 2:
		{
				  //信息查询
				  system("clear");
				  printf("\t\t\t\t\t\t欢迎进入信息查询版块!\n");
				  printf("\t\t\t\t\t\t请输入要查询的学生编号:");
				  scanf("%d", &j);
				  getchar();
				  //printf("%d\n",j);   		//检测输入是否成功,调试程序用
				  FindStu(head, j);    		//查询并输出
				  printf("\n\t\t\t\t\t\t请输入回车键返回主菜单!");
				  getchar();
				  system("clear");
				  break;
		}
		case 3:
		{
				  //成绩统计
				 system("clear");
			     j = 0;
	             while (5 != j)		   	//循环进入子菜单选择
	             {
	             printf("\t\t\t\t\t\t欢迎进入成绩统计版块!\n\n");
	             printf("\t\t\t\t\t\t1、90分以上学生统计\n\n");
	             printf("\t\t\t\t\t\t2、80分以上学生统计\n\n");
	             printf("\t\t\t\t\t\t3、及格学生统计\n\n");
	             printf("\t\t\t\t\t\t4、不及格学生统计\n\n");
	             printf("\t\t\t\t\t\t5、返回\n\n");
	
	            printf("\t\t\t\t\t\t请输入您的选择编号:");
	            scanf("%d", &j);
				if( j<0 ||j>5)
				{
					printf("\t\t\t\t\t\t输入有误,请重新输入!\n\n");
					break;
				}
				if(j==5)
				{
					break;
				}
				getchar();
				printf("\t\t\t\t\t\t输入科目选项:chinese english math\n");
				printf("\t\t\t\t\t\t请输入科目:");
				scanf("%s",subname);
				getchar();
				
				if(strcmp(subname,"chinese")==0)
	            {
		         printf("\t\t\t\t\t\t学号\t姓名\t语文成绩\n");
	            }
	            else if(strcmp(subname,"english")==0)
	            {
		         printf("\t\t\t\t\t\t学号\t姓名\t英语\t成绩\n");
	            }
	            else if(strcmp(subname,"math")==0)
	            {
		         printf("\t\t\t\t\t\t学号\t姓名\t数学\t成绩\n");
	            }
	            else{
		         printf("\t\t\t\t\t\t科目输入错误,请重新输入\n");
		        break;
	           }
				if (1 == j) Count(head, subname, 90, 100);
				else if (2 == j) 	Count(head, subname, 80, 100);	
				else if (3 == j) 	Count(head, subname, 60, 100);	
				else if (4 == j)    Count(head, subname, 0, 60);
				}
				printf("\t\t\t\t\t\t请输入回车键返回主菜单!\n");     //此处本意按任意键返回,但是任意键的话,需要按键A,再按回车确定
				getchar();			//则会连续收到两个按键,造成错误读入,可以改进scanf接收字符串,
				system("clear");			
				break;
				  
			
		}
		case 4:
		{
			      //Rank_Node(&head);
				  //printNode2(head);
				  //成绩排序
				  system("clear");
				  printf("\t\t\t\t\t\t欢迎进入成绩排序版块,请输入科目:\n");
				  printf("\t\t\t\t\t\t请输入科目(科目备选 chinese english math):");
				  scanf("%s",subname);
				  getchar();
				  
				  
				  Rank(head, subname);  			//排序并输出
				  
				  printf("\n\t\t\t\t\t\t请输入回车键返回主菜单!\n");
				  getchar();
				  system("clear");
				  
				  break;
		}
		case 5:
		{
				  //保存退出
				  SaveQuit(head);				//文件操作,保存并退出
				  free(head);
				  return 0;
		}
		case 6:
		         //全部打印
				 printf("\t\t\t\t\t10秒后,自动跳转,请耐心等待\n");
				 printNode(head);
				 sleep(10);
				 break;
		default:
		{
				   printf("\t\t\t\t\t\t输入有误,按回车键重新选择!\n");	//主菜单错误输出检测
				   getchar();
				   system("clear");
		 }
		}
	}
	

     return 0;
}

截图:

      

      

     

     

项目总结:

        自己在使用fsanf的时候,以为它可以格式化,导致从文件读取内容失败,fscanf(fp, "%d  %s  %s  %f  %s  %f  %s",...),用户体验方面,一定要重视,前期做的时候,用户需要输入的多一点,这无疑让用户感到体验不好,自己在这方面的容粗处理也得写不少,所以在后期改的时候,将用户输入这方面改为选项,只需要选1,2,3,就可以实现用户想要的。

 

 

 

 

 

 

 

阅读更多

扫码向博主提问

Lawrence_121

非学,无以致疑;非问,无以广识
去开通我的Chat快问
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页