一个学生成绩管理系统

目录

主要功能

代码实现

一.包括的头文件和一些函数

二,欢迎界面

三,将文件格式化写入文件并储存

四,输入密码的函数,储存到文件中

五,输入成绩

六,打印,将数据显示在屏幕

七,从文件读出数据

八,查找并修改数据

九,添加数据

十,删除数据

十一,退出

十二,排序

十三,创建新数据链

十四,计算总和

十五,修改密码

十六,theOther的函数

主函数

运行

存在错误


主要功能

该管理系统包括了

1.加载所有数据 ,2.创建新数据链 ,3.查找或修改数据,4.删除数据据链,5.排序,6.统计总数 ,7.修改密码,8.theOther,9.退出程序       的功能。

该系统能够将写进去的数据储存到data.txt文件中,该文件放在D盘,后续可将该文件重新读入到系统中。

创新点是加了一个欢迎弹窗,一个进入输入密码的简单程序(密码文件在D:\\data.txt),最后theOther是无聊时玩的小玩意。

添加了的东西单纯对于一个简略的学生管理系统可能会有些无聊。

代码实现

一.包括的头文件和一些函数

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include<malloc.h>
#include<time.h>
#include<Windows.h>

#define NULL 0
#define RoadeKey "D:\\key.txt"
#define RoadeDsta "D:\\data.txt"

typedef struct student {
	int number;
	char name[100];
	double Chinese;
	double maths;
	double English;
	double total;
	struct student* next;
}student;
void Welcome();                       //欢迎界面,显示功能
student* inTurnNumber(student* inTurn1);  //无厘头的东西,给学号进行排序
void keyopen();                       //登录时输入密码
student* createStudent();             //创建一个链表
int input(student* p1);               //为creatsStudent()服务
void output(student* p1);              //打印data
void inputData(student* m1,char a[]);            //将数据格式化写入data.txt
student* printDataFromFile();           //从文件中读出数据
student* seek(student* p1);         //查找数据,目前只能通过number,会成为一个累赘
student* addData(student* m2);        //插入newData到传入链表前头,并将新链表打印出
student* deletData(student* p1);       //输入nuber,删除结点
void sum(student* p1);
void changeKey();
void end();                          //退出系统
void haveFun();

二,欢迎界面

void Welcome() {
    printf("\n");
	printf("***********************WELCOME!!****************************\n");
	printf("  1.加载所有数据       2.创建新数据链\t\n");
	printf("  3.查找或修改数据     4.删除数据\t\n");
	printf("  5.排序               6.统计总数\t\n"); 
	printf("  7.修改密码           8.theOther\t\n");
	printf("  9.退出程序       \t\n");
	printf("____________________________________________________________\n");
}

三,将文件格式化写入文件并储存

void inputData(student* m1,char a[]) {   //将数据格式化写入文件
	if (m1 == NULL) 	return;   //牛逼,原来这就是什么都不返回
	FILE* fp;
	errno_t no = fopen_s(&fp, RoadeDsta,a);
	if (no) {
		printf("didn't open the data\n");
		exit(1);//似乎这个也可以删去了
	}	
	fprintf(fp, "%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", m1->number, m1->name, m1->Chinese, m1->maths, m1->English, m1->total);
	while (m1->next != NULL)
	{    
		m1 = m1->next;
		fprintf(fp, "%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", m1->number, m1->name, m1->Chinese, m1->maths, m1->English, m1->total);
	}
	free(m1);
	rewind(fp);
	fclose(fp);   //一开始忘了这个,无法打开第二次
}

四,输入密码的函数,储存到文件中

void keyopen()
{
	char a1[11]={0}, a2[11]={0};
	int n = 5;  char ch;
	char a;
	FILE* pFile;
	errno_t no = fopen_s(&pFile, RoadeKey, "a+");
	if (no == 1) exit(1);//打开失败
	a=fgetc(pFile);
	if (a ==  -1) {         //或者EOF,当fgetc读取失败返回-1,读取成功返回读取的字符
		printf("did't find the key,please create new key,must 10 character!\n");
		scanf_s("%s", a1, 11);  //储存用户创建的key
		while ((ch = getchar()) != '\n');  //刷新缓存区
		while (strlen(a1) != 10) {    //strlen统计字符个数
			printf("the key must to be 10 numbers\nplease try again\n");
			//printf("%d", strlen(a1));        //检测strlen对于scanf输入
			scanf_s("%s", a1, 11);             //对于scanf_s这个函数还有没搞明白的;定义的数组为【10】,但是却是11,strlen才有用
			while ((ch = getchar()) != '\n');
		}
		printf("please try again to check your first input!\n");
		scanf_s("%s", a2, 11);
		if (strcmp(a1,a2) == 0) {  //对比两次输入的key是否一致,一致返回0
			printf("the key was created!\n");
			fputs(a1, pFile);   //储存key
		}
	}
	else {
		rewind(pFile);
		printf("please enter the key\n");
		scanf_s("%s", a1, 11);//难道你也要读‘0’???10,打印不出来
		while ((ch = getchar()) != '\n');
		fgets(a2,11,pFile);//fgets计算字符长度加上结尾的'0'
		//printf("%s", a1);  见131行
		//printf("\n%d\n", strlen(a1));
		//printf("%s", a1);    //   测试
		while (strcmp(a1, a2) != 0) {  //按ascll码比较俩个数的大小
			n--;
			printf("the key was wrong,you have %d chance to try it\n", n+1);
			scanf_s("%s", a1, 11);
			while ((ch = getchar()) != '\n');
			if (n == 0) {
				printf("the progress will close\n");
				exit(1);
			}
		}
		printf("the key was right!\n");

	}
	printf("***********************WELCOME!!****************************\n");
	
	fclose(pFile);
}

五,输入成绩

int input(student* p1) { 

	printf("please create a Student's data\n(number is 0 to exit.\n");
	printf("number: "); scanf_s("%d", &p1->number);
	if (p1->number == 0) return 0;
	printf("name: "); scanf_s("%s", &p1->name, 100);
	printf("Chinese: "); scanf_s("%lf", &p1->Chinese);
	printf("maths: "); scanf_s("%lf", &p1->maths);
	printf("English: "), scanf_s("%lf", &p1->English);
	p1->total = p1->Chinese + p1->maths + p1->English;
	return 1;
}

六,打印,将数据显示在屏幕

void output(student* p1) {    //打印时一定要注意指针,不要将头指针给送进去,不然你就完了
	printf("the list is here:\n");
	printf("number\tname\tChinese\tmaths\tEnglish\ttotal\n");
	printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", p1->number, p1->name, p1->Chinese, p1->maths, p1->English, p1->total);
	while (p1->next!= NULL) {   //p1!=NULL会多打一行乱码,why,改了之后好像没事了
		p1 = p1->next;
		printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", p1->number, p1->name, p1->Chinese, p1->maths, p1->English, p1->total);
	}
}

七,从文件读出数据

student* printDataFromFile() {
	int n = 0; int n1;
	FILE* fp;
	student* head1, * m1, * m2, * head;
	m2 = m1 = (student*)malloc(sizeof(student));
	head=head1 = NULL;
	errno_t no = fopen_s(&fp, RoadeDsta, "r");
	if (no) {     //返回为1,打开失败
		printf("didn't open the data or no data!!!\n");return head;
	}
	fseek(fp, 0L, 2); n1 = ftell(fp); rewind(fp);
	if (n1 ==0) {
		printf("no data!\n");	return head; //exit(1);一开始加这个,导致没有数据,程序停止运行
	}
	fscanf_s(fp, "%d", &m1->number);
	fscanf_s(fp, "%s", m1->name, 100);
	fscanf_s(fp, "%lf", &m1->Chinese);
	fscanf_s(fp, "%lf", &m1->maths);
	fscanf_s(fp, "%lf", &m1->English);
	fscanf_s(fp, "%lf", &m1->total);
	while (n1!=ftell(fp)) {
		n++;
		if (n == 1)head = m1;
		else m2->next = m1;
		m2 = m1;
		m1 = (student*)malloc(sizeof(student));
		//对m1->name不必要&,其本身为地址;
		fscanf_s(fp, "%d", &m1->number);
		fscanf_s(fp, "%s", m1->name, 100);
		fscanf_s(fp, "%lf", &m1->Chinese);
		fscanf_s(fp, "%lf", &m1->maths);
		fscanf_s(fp, "%lf", &m1->English);
		fscanf_s(fp, "%lf", &m1->total);
	}
	m2->next = NULL;
	free(m1);    //为什么将m1释放会乱码	
	rewind(fp);
	head1 = head;
	output(head1);
	/*printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", head1->number, head1->name, head1->Chinese, head1->maths, head1->English, head1->total);
	while (head1->next != NULL)
	{
		head1 = head1->next;
		printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", head1->number, head1->name, head1->Chinese, head1->maths, head1->English, head1->total);
	}*/
	fclose(fp);
	return head;
}

八,查找并修改数据

student* seek(student* p1) {
	int n; int b = 0;
	student* m1, * chaker2;
	chaker2 = m1 = p1;
	printf("please enter the students' number to find the data you want.\n");
	scanf_s("%d", &n); 
	if (m1->number == n) {
		chaker2 = m1;
		printf("number\tname\tChinese\tmaths\tEnglish\ttotal\n");
		printf(" % d\t % s\t % .2lf\t % .2lf\t % .2lf\t % .2lf\t\n", m1->number, m1->name, m1->Chinese, m1->maths, m1->English, m1->total);
		printf("Do you want to change the data? \n1to go on and 0 to quit.\n");
		scanf_s("%d", &n);
		if (n == 0) { return p1; }
		else {
			input(m1);
			m1->next = chaker2->next;
			return p1;
		}
	}
	while (m1->next != NULL) {
		chaker2 = m1;
		m1 = m1->next;
		if (m1->number == n) {
			b = 1;
			printf("number\tname\tChinese\tmaths\tEnglish\ttotal\n");
			printf(" % d\t % s\t % .2lf\t % .2lf\t % .2lf\t % .2lf\t\n", m1->number, m1->name, m1->Chinese, m1->maths, m1->English, m1->total);
			printf("\n");
			printf("Do you want to change the data? \n1to go on and 0 to quit.0 to quit.\n");
			scanf_s("%d", &n);
			if (n == 0) { return p1; }
			else {
				input(m1);
				chaker2->next = m1;
				return p1;
			}
		}	
	}
	if ((m1->next == NULL) && (b == 0)) {
		printf("can't find the number!\n ");
	}
	return p1;
}

九,添加数据

student* addData(student* m2) {
	student* p1, * p2, * head, * head1;
	//output(m2);//会打印多一行,why11052050->11061556现在不会了
	p1 = p2 = (student*)malloc(sizeof(student));
	printf("add students'data,number is 0 to quiz\n");
	input(p1);
	head = p1;	p2 = p1;
	while (p1->number != 0) {
		p2->next = p1;
		p2 = p1;
		p1 = (student*)malloc(sizeof(student));
		input(p1);
	}
	free(p1);
	head1 = head;
	p2->next = m2;
	output(head);
	printf("the data was added!\n");
	return head1;

}

十,删除数据

student* deletData(student* p1) {
	student* m1, * m2, * m3, * m4;
	m4 = m3 = m1 = p1;
	m2 = NULL;
	printf("Please enter the student's number that you want to delet\n");
	int n; int c=0;
	scanf_s("%d", &n);
	while ((n != m1->number) && (m1->next != NULL)) {
		m2 = m1; m1 = m1->next;
	}
	if (n == m3->number) {
		m3 = m3->next; m4 = m3;
	}else if(n == m1->number) m2->next = m1->next;                                                                   //最后一个数据怎么办11122025
	 else {
		printf("did't find the data.\n"); 
		return p1;
	  }
	printf("the data was deleted!\n");
	printf("number\tname\tChinese\tmaths\tEnglish\ttotal\n");
	printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", m3->number, m3->name, m3->Chinese, m3->maths, m3->English, m3->total);
	while (m3->next != NULL)
	{
		m3 = m3->next;
		printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", m3->number, m3->name, m3->Chinese, m3->maths, m3->English, m3->total);
	}
	return m4;
}

十一,退出

void end() {
	exit(1);
}

十二,排序

student* inTurnNumber(student* inTurn1) {
	student* inTurn2 = inTurn1;
	student* inTurn3 = inTurn1;
	int b, c; int j = 0, i = 1;
	double a[2000] = { 0 };//最多容纳2000个数据进行排序
    int classify = 0;
	printf("to turn by what?enter the serial number.\n1 is number.\t2 is Chinese.\n3 is maths.\t4 is English.\t5 is Total.\n");
	scanf_s("%d", &classify);	
	if(classify==1) a[j] = inTurn2->number;
	else if(classify==2) a[j] = inTurn2->Chinese;
	else if (classify == 3) a[j] = inTurn2->maths;
	else if (classify == 4) a[j] = inTurn2->English;
	else if (classify == 5) a[j] = inTurn2->total;
	else { printf("There is not the choice!BYB\n"); return inTurn1; }
	while (inTurn2->next != NULL) {
		j++;   //j不表示个数
		inTurn2 = inTurn2->next;
		if (classify == 1) a[j] = inTurn2->number;
		else if (classify == 2) a[j] = inTurn2->Chinese;
		else if (classify == 3) a[j] = inTurn2->maths;
		else if (classify == 4) a[j] = inTurn2->English;
		else if (classify == 5) a[j] = inTurn2->total;
	}
	inTurn2 = NULL;
	/*for (int i = 0; i <=j; i++) {
		printf("%lf\n", a[i]);
	}*/
	printf("\n");
	for (int i = 0; i < j ; i++) {
		b = a[i]; c = i;
		for (int k = (i + 1); k <= j; k++) {
			if (b < a[k]) {
				b = a[k];
				c = k;
			}
		}
		a[c] = a[i];
		a[i] = b;
	}
	printf("\n");
	/*for (int i = 0; i <= j; i++) {
		printf("%d\t", a[i]);
	}
	printf("\n");*/
	//printf("%d\n", j);
	i = 0;
	printf("number\tname\tChinese\tmaths\tEnglish\ttotal\n");
	while (i != (j+1)) {
		if(classify==1) while (a[i] != inTurn3->number) inTurn3 = inTurn3->next;
		else if (classify == 2) while (a[i] != inTurn3->Chinese) inTurn3 = inTurn3->next;
		else if (classify == 3) while (a[i] != inTurn3->maths) inTurn3 = inTurn3->next;
		else if (classify == 4) while (a[i] != inTurn3->English) inTurn3 = inTurn3->next;
		else if (classify == 5) while (a[i] != inTurn3->total) inTurn3 = inTurn3->next;
		printf("%d\t%s\t%.2lf\t%.2lf\t%.2lf\t%.2lf\t\n", inTurn3->number, inTurn3->name, inTurn3->Chinese, inTurn3->maths, inTurn3->English, inTurn3->total);
		i++; 
	    inTurn3 = inTurn1;
	}
//	inTurn2->next = NULL;
	return inTurn2;//inTurn2是空的
}

十三,创建新数据链

student* createStudent() {                     //创建链表
		struct student* head, * p1, * p2;         //定义一个头指针,两个工作指针,节点数n初始化为0
		int n = 0;              //将头指针指向空,为p1,p2申请内存
		head = NULL;
		p2 = p1 = (struct student*)malloc(sizeof(struct student));
		int r = input(p1);
		if (r == 0) 	return head;
		while (p1->number != 0)          //开始循环,以num为0作为结束条件
		{
		
			n++;                             //结点数加一
			if (n == 1)head = p1;                 //将p1给头指针
			else p2->next = p1;         //将p1链到p2尾部
			p2 = p1;                         //将p1赋给p2
			p1 = (struct student*)malloc(sizeof(struct student));     //再次为p1申请内存
			input(p1);
		}
		p2->next = NULL;          //循环结束后,将p2的尾部链到空,避免成为野指针
		free(p1);                                            //将p1的空间释放
		return head;
	}

十四,计算总和

void sum(student* p1) {
	student* sum = p1; int t = 1, pass1 = 0, pass2 = 0, pass3 = 0, pass4 = 0;
	double sum1=0, avg1 = 0, PASS1 = 0, sum2 = 0, avg2 = 0, PASS2 = 0, sum3 = 0, avg3 = 0, PASS3 = 0, sum4 = 0, avg4 = 0, PASS4 = 0;
	 sum1 = sum->Chinese; sum2 = sum->maths; sum3 = sum->English; sum4 = sum->total;
	if (sum->Chinese >= 60) pass1++;
	if (sum->maths >= 60) pass2++;
	if (sum->English >= 60) pass3++;
	if (sum->total >= 60) pass4++;
	while (sum->next != NULL) {
		sum = sum->next;
		sum1 += sum->Chinese; sum2 += sum->maths; sum3 += sum->English; sum4 += sum->total;
		t++;
		if (sum->Chinese >= 60) pass1++;
		if (sum->maths >= 60) pass2++;
		if (sum->English >= 60) pass3++;
		if (sum->total >= 60) pass4++;
	}
	avg1 = sum1 / t; avg2 = sum2 / t; avg3 = sum3 / t; avg4 = sum4 / t;
	PASS1 = (double)pass1 / t;	PASS2 = (double)pass2 / t;	PASS3 = (double)pass3 / t;
	printf("A total of %d dtudents took the examination,as follows:\n",t);
	printf("the sum\t    average score\t     percent of pass\t\n");
	printf("Chinese\t         %.2lf\t               %.2lf\t\n", avg1, PASS1);
	printf("maths\t         %.2lf\t               %.2lf\t\n", avg2, PASS2);
	printf("English\t         %.2lf\t               %.2lf\t\n", avg3, PASS3);
	printf("total\t         %.2lf\t               NULL\n", avg4);
	
}

十五,修改密码

void changeKey() {
	FILE* fp; char ch;
	errno_t no = fopen_s(&fp, RoadeKey, "r");
	if (no) { printf("ERRNO!"); return; }
	char key1[11] = { 0 }; char key2[11] = { 0 };//why 如果是10,运行时提示周围堆栈已损坏
	int i = 0;
	fgets(key1, 11, fp); 
	/*while ((key1[i] = fgetc(fp)) != EOF) i++;*/
	/*for (int i = 0; i < 10; i++) {
		key1[i] = fgetc(fp);
	}*/
	fclose(fp);
	//printf("%s\n",key1);
	printf("Please input the Initial password:\n");
	scanf_s("%s", key2, 11);
	if (strcmp(key1, key2) != 0) {  //相同,返回0
		printf("the password was wrong!!GOODBYB!\n");
		return;
	}
	
	else {
		printf("Create your new password:\n");
		scanf_s("%s", key2, 11);  
		while (ch=(getchar()) != '\n');
		while (strlen(key2) != 10) {   
			printf("the key must to be 10 numbers\nplease try again\n");
			scanf_s("%s", key2, 11);            
			while ((ch = getchar()) != '\n');
		}
		errno_t no = fopen_s(&fp, RoadeKey, "w");
		if (no) { printf("ERRNO!"); return; }
		fputs(key2, fp);
		fclose(fp);
	}
}

十六,theOther的函数


void haveFun() {
	char color[10] = "color ";
	char a1[2], a2[2];
	printf("0.黑色\t1.蓝色\t2.绿色\t3.浅绿色\t4.红色\t5.紫色\t6.黄色\t7.白色\t8.灰色\t9.淡蓝色\n ");
	printf("A.淡绿色\tB.淡浅绿色\tC. 淡红色\tD.淡紫色\tE.淡黄色\tF.亮白色\n");
	printf("输入一个数字或一个字母(背景)\n");
	scanf_s("%s", a1,2);
	printf("输入第二个数字或字母(前景)\n");
	scanf_s("%s",a2,2);
	if ((strcmp(a1, a2)) == 0)printf("Nothing happened sometime!");
	strcat_s(color, a1); strcat_s(color, a2);
	printf("%s",color);
	system(color);
}

主函数


int main() {//学生人数统计
	int q, q1 = 0; char a[][2] = { "a","r","w"};//a追加,r只读
	student* p1, * p2;
	MessageBox(NULL,TEXT("HelloWord!This is MessageBox."),TEXT("你好,这里是弹窗。"), MB_OK | MB_ICONASTERISK);//好玩的东东
	keyopen();
	Welcome();
	printf("intut a number to go on:\n");
	int i = scanf_s("%d", &q);
	/* if (i != 1) {    //如何判断输入的东西不合法
		printf("input errno!!try again.\n"); scanf_s("%d", &q);
	}*/
	while (true) {
		switch (q)
		{
		case 1:p1 = printDataFromFile();
			break;
		case 2: {p1 = createStudent(); inputData(p1, a[0]); }
			  break;
		case 3: {p1 = printDataFromFile(); p1 = seek(p1); inputData(p1, a[2]); }
			  break;
		case 4: {p1 = printDataFromFile(); p1 = deletData(p1); inputData(p1, a[2]); }
			  break;
		case 5: {p1 = printDataFromFile(); p1 = inTurnNumber(p1); }
			  break;
		case 6: {p1 = printDataFromFile(); sum(p1); }
			  break;
		case 7:changeKey();
			break;
		case 8: {getchar();  haveFun(); }
			  break;
		case 9:end();
			break;
		default:printf("%d is not a command!!\n", q);
			break;
		}
		printf("Any key to continue_\n");
		getchar(); getchar();
		Welcome();
		printf("输入一个序号\n");
		scanf_s("%d", &q);
	}
	return 0;
}

运行

1,弹窗界面,可在mian中修改。

ac9721e8ef8648dd81bf7a98c07e9ad7.png

2, 一个输入密码的判断机制,五次错误后强制退出
abf6483fa62d4988849c8ab02394e7b5.png

 3,欢迎界面

注:有些序号如6.统计所有数据,需要在D盘中存有data.txt,然后运行函数将它读出排序倘若D盘中没有txt,则会报错退出程序,原因:没有对其进行错误判断。后续可自行添加。(但有些函数添加了判断,如1,加载所有数据,没有数据则打印出“no data !”)

13694b6f4c024537a902d08a1e1bc558.png

 4,theOther

e076776316f54ddd97263675900bacfe.png

5,data

b0a86b20077c4f499da4ebe952880cbc.png

存在错误

1,排序的函数过于冗长,但我还没找到更好颁发。

2,有些函数没有错误判断机制,但不多(主要是该程序已经告一段落,不想再改了)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值