【C语言】学生管理系统

news2024/11/19 23:17:13

        学生管理系统是一个用于管理学生信息、成绩、课程等数据的软件系统。在本文中,我们将使用C语言来实现一个简易的学生管理系统,包括学生信息的录入、显示、查询等功能。我们将使用文件来存储学生信息,以便实现持久化存储。        

        该学生管理系统将实现以下功能:程序使用帮助,增加学生信息  ,查找学生信息,删除学生信息 ,保存文件,显示当前信息,修改学生信息   ,刷新学生成绩 ,退出程序。下面将讲解整体程序的实现,并对程序进行讲解,如果需要源代码可通过目录前往后文进行获取。

目录

程序实现

包含头文件

数据结构的设计

 宏定义

主函数

函数声明

函数设计

菜单

程序使用说明书

添加学生信息

查询学生信息

删除学生信息

将学生信息保存到文件

展现目前学生信息

修改学生信息

刷新文件

退出程序

源代码


程序实现

        以上为程序的整体实现逻辑,该程序使用一个.c文件来实现。程序通过设计数据结构来对学生信息进行管理和设计,在主函数中使用自定义函数来进行功能的实现,在程序前面进行函数声明来保证函数的正常使用。


包含头文件

#inlcude<stdio.h>

#include<stdlib.h>

#include<string.h>


数据结构的设计

struct student
{
	char StuID[LEN];//学生学号 
	char Stuname[LEN];
	int Stuage;
	char Stusex;
	float score[3]; //各科成绩 
}stu[N];

         设计结构体包含学生学号,姓名,年级,性别,各科成绩。

        声明结构体数组stu[N],表示有N个学生的管理名额,每一个都是student结构体变量。


 宏定义

#define LEN 15//姓名和学号的最大字符数 
#define N 50//最大学生人数

主函数

int main()
{
	int num;//num是菜单选项 
	while (t)//t是全局变量,用tuichu函数来控制循环是否继续 
	{
		menu();//输出主菜单界面 
		printf("您好,请输入菜单编号:");
		scanf("%d", &num);
		switch (num)
		{
		case 1: help(); break;
		case 2: increase(); break;
		case 3: seek(); break;
		case 4: de(); break;
		case 5: save(); break;
		case 6: present(); break;
		case 7: modify(); break;
		case 8: flush(); break;
		case 9: tuichu(); break;
		default:printf("输入有误,请重新输入!");
		}


	}

	system("pause");
	return 0;
}

        设计一个操作菜单,用switch分支语句来对程序进行操控,除退出选项外在while循环内可以一直进行选择操作。


函数声明

//函数声明
void menu();//主菜单函数 
void help();//使用帮助 
void increase();//增加学生信息  
void seek();//查找学生信息
void de();//删除学生信息 
void save();//保存文件
void present();//显示当前信息
void modify();//修改学生信息   
void flush();//刷新学生成绩 
void tuichu();//退出函数 

        因为该程序是将所有函数在main函数后面进行设计的,所以在main函数前面需要进行函数的声明,保证可以正常运行。


函数设计

下面将对程序中的函数进行逐一设计并讲解,略复杂代码会带有注释。

菜单

void menu()
{
	printf("\n\n");
	printf("*****************************************************\n");
	printf("*----------------------------------------------------\n");
	printf("*                 学生信息管理系统                  *\n");
	printf("*****************************************************\n");
	printf("********************系统功能菜单*********************\n");
	printf("----------------------     --------------------------\n");
	printf("*****************************************************\n");
	printf("**    1、使用帮助       *     2、增加学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    3、查询学生信息   *     4、删除学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    5、保存当前信息   *     6、显示当前信息      **\n");
	printf("*****************************************************\n");
	printf("**    7、修改学生信息   *     8、刷新学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    9、退出系统       *                          **\n");
	printf("*****************************************************\n");
	printf("-----------------------------------------------------\n");

}

程序使用说明书

void help()
{
	printf("\n这是一个学生信息管理系统,为了帮助您更快的了解使用它,请先仔细阅读以下注意事项:\n");
	printf("\n                  注意事项:                    \n ");
	printf("\n       1、请根据提示进行操作!\n");
	printf("\n       2、初次使用请先选择增加学生信息!\n");
	printf("\n       3、修改或者增加学生信息后切记保存!\n");
	printf("\n       4、如果数据有错误,请先修改再保存!\n");
	printf("\n       5、若您之前使用过,下次进入系统请先刷新学生信息!\n");
	printf("\n       6、在添加学生时,用两个字符代表不同的性别,比如男用‘M’代替,女用‘W’代替!\n");
	printf("\n       7、保存或者刷新时,输入的文件名后缀请使用.txt,比如: stu.txt,系统会在源程序\n");
	printf("\n          “学生管理系统.exe”的相同目录建立一个.txt文件来保存学生信息,您可以查看\n");
	printf("\n          该文件,但非专业人员不要轻易改动,否则会造成刷新数据异常或刷新失败!\n");
	printf("\n       8、学生信息包括:姓名、学号、性别、年龄、C语言成绩、高数成绩、英语成绩等!\n");
	printf("\n       9、使用遇到任何问题请与我们联系,邮箱:13991770359@163.com\n");
	printf("\n       10、最后感谢您的使用!\n");
	system("pause");
}

添加学生信息

void increase()
{
	int i = n, j, flag, m = 0;//i代表增加学生信息过程中任意时刻的学生人数 
	printf("\n请输入待增加的学生人数:\n");
	scanf("%d", &m);
	if (m > 0) {
		do {
			flag = 1;
			while (flag)
			{
				flag = 0;
				printf("请输入第%d位学生的学号:\n", i + 1);//第几位学生从1开始计数,而stu[]从零开始,需要加1 
				scanf("%s", stu[i].StuID);
				//判断学号是否重复
				for (j = 0; j < i; j++) 
				{
					if (strcmp(stu[i].StuID, stu[j].StuID) == 0) 
					{
						printf("该学号已经存在,请重新输入!\n");
						flag = 1;
						break;
					}
				}
			}
			printf("请输入第%d位学生姓名:\n", i + 1);
			scanf("%s", stu[i].Stuname);
			printf("请输入第%d位学生年龄:\n", i + 1);
			scanf("%d", &stu[i].Stuage);
			getchar();//处理上面输入的换行符,不然系统会把换行符当做一个字符赋值给性别 
			printf("请输入第%d位学生性别:\n", i + 1);
			scanf("%c", &stu[i].Stusex);
			printf("请输入第%d位学生的C语言成绩:\n", i + 1);
			scanf("%f", &stu[i].score[0]);
			printf("请输入第%d位学生的高数成绩:\n", i + 1);
			scanf("%f", &stu[i].score[1]);
			printf("请输入第%d位学生的大学英语成绩:\n", i + 1);
			scanf("%f", &stu[i].score[2]);
			i++;
		} while (i < n + m);//只要当前学生人数还没到达添加后的总人数,就得继续添加		
	}
	n += m;// 添加完成,系统人数n的值也要增加 
	printf("添加完成!!!\n");
	system("pause");
}

        该函数通过控制n,m的大小来控制do while实现添加到目标人数。在函数运行结束后也对实时人数进行更新。

查询学生信息

void seek()
{
	int i, num, flag;
	char s1[LEN + 1];
	printf("*****************************\n");
	printf("**-------1.按学号查询------**\n");
	printf("**-------2.按姓名查询------**\n");
	printf("**-------3.退出本菜单------**\n");
	printf("*****************************\n");
	while (1)
	{
		flag = 0;
		printf("请输入子菜单:");
		scanf("%d", &num);
		switch (num)
		{
		case 1:
			printf("请输入需要查找学生的学号:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].StuID, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 2:
			printf("请输入需要查找学生的姓名:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].Stuname, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 3: return;
		default: printf("请在1--3之间输入\n");
		}
		if (flag == 0)
			printf("找不到该学生!\n请重新输入!");
	}
}

        设置两种查询方法,姓名查找和学号查找。利用switch选择语句进行选择要进行操作的步骤,在两个选择操作中均用strcmp进行stu与s1判断。初始用flag = 0作为一个标识,如果输入学号查询不到就会进行报错“找不到该学生!请重新输入!”,查找到的话进行打印信息并设置flag为1。

删除学生信息

void de()
{
	int i, j, flag;
	char s1[LEN];
	printf("请输入需要删除的学生学号:\n");
	scanf("%s", s1);
	flag = 0;
	for (i = 0; i < n; i++)
	{
		if (strcmp(s1, stu[i].StuID) == 0)
		{
			flag = 1;
			for (j = i; j < n - 1; j++)
			{
				stu[j] = stu[j + 1];//直接把后面的学生都往前移动一位 
			}
		}
		if (flag == 1) break;//说明已经找到了需要删除的学生,结束循环 
	}
	if (0 == flag)
	{
		printf("该学号不存在!!!\n");
	}

	if (1 == flag)
	{
		printf("删除成功\n");
		n--;
	}
	system("pause");
}

        如查找方法一样先进行查找信息,然后将该信息之后的所有学生信息全部向前移动一位,覆盖掉该信息,最后如果删除成功的话将学生数量-1。

将学生信息保存到文件

void save()//把学生信息保存到文件 
{
	int i;
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入要保存的文件名:\n");
	scanf("%s", filename);
	if ((fp = fopen(filename, "w")) == NULL)// “w” 以只读模式建立文本文件,若文件存在则文件长度清0
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	for (i = 0; i < n; i++)
		if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)//云笔记记录
			printf("保存失败!!\n");
	printf("保存成功!!!\n");
	fclose(fp);
	system("pause");
}

        第一个for循环的作用是尝试以只写模式打开一个文件,如果打开失败,则输出错误信息并退出程序。以下为详细解读:

  1. fp 是一个指向 FILE 结构的指针,它将被用于访问文件。
  2. filename 是一个字符串,表示要打开的文件的名称。
  3. fopen 是一个标准库函数,用于打开一个文件。它接受两个参数:文件名和打开模式。
  4. "w" 是打开模式,表示以只写模式打开文件。如果文件不存在,则会创建文件;如果文件已经存在,则会清空文件内容。
  5. == NULL 是一个比较操作符,用于检查 fopen 函数的返回值是否为 NULL,即检查文件是否成功打开。
  6. 如果 fopen 打开文件失败,它会返回 NULL,因此整个条件表达式的结果为真(即非零)。因此,如果打开文件失败,if 语句中的代码块会被执行。

        第二个for循环的作用是将结构体数组中的数据写入文件,并在写入失败时输出错误信息。下面是对该代码的详细解读:

        整个 fwrite 函数的作用是将 stu[i] 结构体的内容以二进制形式写入文件中。

接下来是 if 语句,它检查 fwrite 函数的返回值是否等于 1。如果 fwrite 函数成功写入了一个数据项,它会返回写入的数据项的个数(即 1),否则返回值不等于 1

        如果 fwrite 函数返回值不等于 1,则说明写入失败,printf 函数会输出保存失败的信息。        

  1. fwrite 是一个标准库函数,用于将数据块写入文件中。它接受四个参数:要写入的数据的地址、每个数据项的大小、数据项的个数和文件指针。
  2. &stu[i] 表示结构体数组 stu 中第 i 个元素的地址。这个地址作为要写入的数据的地址。
  3. sizeof(struct student) 给出了一个结构体 student 的大小,这是要写入的每个数据项的大小。
  4. 1 表示要写入的数据项的个数。
  5. fp 是一个指向 FILE 结构的指针,它指向要写入的文件。

        

展现目前学生信息

void present()//展现出所有学生信息
{
	int i;

	if (n == 0)
	{
		printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
	}
	else
	{
		printf("现在共有%d名学生:\n", n);
		printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
		for (i = 0; i < n; i++)
		{
			printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
		}
	}

	system("pause");
}

        n代表当前学生数量,判断n的数量来进行打印信息。

修改学生信息

void modify()//修改学生信息
{
	int i, flag;
	char ID[LEN], name[LEN], sex;
	int age;
	float score;
	printf("请输入需要修改的学生姓名:\n");
	getchar();//清除缓存中的回车,使gets正确读取
	gets(name);

	while (1)
	{
		flag = 0;
		for (i = 0; i < n; i++)
		{
			if (strcmp(name, stu[i].Stuname) == 0)//string.h
			{
				flag = 1;
				int num;//用于switch函数的子菜单 
				printf("***************************************************\n");
				printf("*----1.修改学号--------  -  -----2.修改性别-------*\n");
				printf("*----3.修改年龄--------  -  -----4.修改C语言成绩--*\n");
				printf("*----5.修改高数成绩----  -  -----6.修改英语成绩---*\n");
				printf("*-------------------7.退出本菜单------------------*\n");
				printf("***************************************************\n\n");
				printf("请输入子菜单:");
				scanf("%d", &num);
				switch (num)
				{
				case 1:
					printf("请输入新的学号:\n");
					getchar();
					gets(ID);
					strcpy(stu[i].StuID, ID); break;
				case 2:
					getchar();
					printf("请输入新的性别:\n");
					scanf("%c", &sex);
					stu[i].Stusex = sex; break;
				case 3:
					printf("请输入新的年龄:\n");
					scanf("%d", &age);
					stu[i].Stuage = age; break;
				case 4:
					printf("请输入新的C语言成绩:\n");
					scanf("%f", &score);
					stu[i].score[0] = score; break;
				case 5:
					printf("请输入新的高数成绩:\n");
					scanf("%f", &score);
					stu[i].score[1] = score; break;
				case 6:
					printf("请输入新的英语成绩:\n");
					scanf("%f", &score);
					stu[i].score[2] = score; break;
				case 7:
					return; break;
				default:
					printf("请在1--7之间选择!\n");
				}
				if (num > 0 && num < 7)
					printf("修改成功,记得保存哟!!!\n");
				break;//找到学生,结束循环;	
			}
		}
		if (flag == 0)
		{
			printf("没有找到该学生,请重新输入需要修改信息的学生姓名:\n");
			gets(name);
		}
	}
	system("pause");
}

        这段代码的作用是允许用户通过输入学生姓名来修改该学生的各项信息,包括学号、性别、年龄和成绩等。在用户输入学生姓名后,会显示一个子菜单,允许用户选择要修改的信息,然后根据用户的选择进行相应的修改操作。

以下为详细解读:

  1. 首先定义了一个函数 modify,没有参数和返回值。
  2. 在函数内部,使用了一些变量来存储用户输入的学生姓名、学号、性别、年龄以及成绩等信息。
  3. 用户首先被要求输入需要修改信息的学生姓名。
  4. 然后进入一个无限循环 while (1),这个循环会一直运行直到用户选择退出子菜单。
  5. 在循环内部,首先通过一个 for 循环遍历学生数组 stu,查找是否有与用户输入的姓名匹配的学生。
  6. 如果找到了匹配的学生,会显示一个子菜单,让用户选择要修改的信息,包括学号、性别、年龄和各科成绩。
  7. 用户输入相应的信息后,使用 switch 语句根据用户的选择来执行相应的修改操作。
  8. 如果用户选择退出子菜单,会使用 return 语句结束函数的执行。
  9. 如果用户输入了不在 1 到 7 之间的数字,会显示错误信息。
  10. 如果成功进行了修改,会显示修改成功的提示信息。
  11. 如果在整个数组中没有找到匹配的学生,会提示用户重新输入需要修改信息的学生姓名。

刷新文件

void flush()//刷新
{
	int i, k = 0;//k代表刷新过程中学生人数 
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入需要刷新的文件名:\n");
	getchar();               
	gets(filename);
	if ((fp = fopen(filename, "r")) == NULL)//打开文件 
	{
		printf("打开文件失败!\n");
		exit(0);//正常运行程序并退出程序;
	}
	for (i = 0; i < N; i++)//N是最大的学生人数,可在程序开头进行更改 
	{
		if (fread(&stu[i], sizeof(struct student), 1, fp) == 1)// “r” 代表以只读(只从文件读取数据)的方式打开文件
			k++;//记录学生人数 
	}
	n = k;// 把k的值给n													
	if (k == 0)
		printf("刷新失败!!!\n");
	else
		printf("刷新成功!!!\n");
	fclose(fp);
	system("pause");

}

        这段代码的作用是允许用户输入文件名,然后从该文件中读取学生信息,将学生人数存储到全局变量 n 中,并显示相应的提示信息。如果文件打开失败,则会显示错误信息并终止程序的执行。

详细解读:

  1. 首先定义了一个函数 flush,没有参数和返回值。
  2. 在函数内部,定义了一些变量,包括整型变量 i 和 k,以及字符数组 filename 用于存储文件名。
  3. 用户被要求输入需要刷新的文件名。
  4. 使用 getchar() 函数来清除输入缓冲区中的回车符,然后使用 gets() 函数获取用户输入的文件名。
  5. 使用 fopen() 函数以只读的方式打开用户输入的文件名,如果文件打开失败,则显示错误信息并调用 exit(0) 终止程序的执行。
  6. 使用一个 for 循环遍历一个预定义的最大学生人数 N,在每次循环中使用 fread() 函数从文件中读取一个 struct student 结构体的数据,如果成功读取到了数据,则将 k 的值加一,以记录学生人数。
  7. 将 k 的值赋给全局变量 n,以便后续使用。
  8. 如果 k 的值为 0,则显示刷新失败的提示信息,否则显示刷新成功的提示信息。
  9. 使用 fclose() 函数关闭文件。
  10. 使用 system("pause") 函数暂停程序的执行,等待用户按下任意键继续。

退出程序

void tuichu()
{
	int h;//控制是否确认退出 
	printf("即将退出,确认请按1,取消请按0\n");
	scanf("%d", &h);
	if (h == 1)
	{
		t = 0;//t是main函数中while函数是否继续执行的控制条件,是一个全局变量,程序开头已经定义并且赋值位 1
		printf("成功退出,感谢使用!\n");
	}
	if (h == 0)
	{
		printf("退出已取消!\n");
		system("pause");
	}

}

        该代码控制退出程序,如果确认退出,则设置全局变量 t 的值为 0,以终止 main 函数中的 while 循环,并显示相应的提示信息。如果取消退出,则显示取消退出的提示信息,并暂停程序的执行。

源代码

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>//需要用到strcmp函数 

#define LEN 15//姓名和学号的最大字符数 
#define N 50//最大学生人数

int n = 0, t = 1;//n代表当前学生人数,t用来控制整个程序的执行,以及程序的退出; 

//函数声明
void menu();//主菜单函数 
void help();//使用帮助 
void increase();//增加学生信息  
void seek();//查找学生信息
void de();//删除学生信息 
void save();//保存文件
void present();//显示当前信息
void modify();//修改学生信息   
void flush();//刷新学生成绩 
void tuichu();//退出函数 

struct student
{
	char StuID[LEN];//学生学号 
	char Stuname[LEN];
	int Stuage;
	char Stusex;
	float score[3]; //各科成绩 
}stu[N];

int main()
{
	int num;//num是菜单选项 
	while (t)//t是全局变量,用tuichu函数来控制循环是否继续 
	{
		menu();//输出主菜单界面 
		printf("您好,请输入菜单编号:");
		scanf("%d", &num);
		switch (num)
		{
		case 1: help(); break;
		case 2: increase(); break;
		case 3: seek(); break;
		case 4: de(); break;
		case 5: save(); break;
		case 6: present(); break;
		case 7: modify(); break;
		case 8: flush(); break;
		case 9: tuichu(); break;
		default:printf("输入有误,请重新输入!");
		}


	}

	system("pause");
	return 0;
}
void menu()
{
	printf("\n\n");
	printf("*****************************************************\n");
	printf("*----------------------------------------------------\n");
	printf("*                 学生信息管理系统                  *\n");
	printf("*****************************************************\n");
	printf("********************系统功能菜单*********************\n");
	printf("----------------------     --------------------------\n");
	printf("*****************************************************\n");
	printf("**    1、使用帮助       *     2、增加学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    3、查询学生信息   *     4、删除学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    5、保存当前信息   *     6、显示当前信息      **\n");
	printf("*****************************************************\n");
	printf("**    7、修改学生信息   *     8、刷新学生信息      **\n");
	printf("*****************************************************\n");
	printf("**    9、退出系统       *                          **\n");
	printf("*****************************************************\n");
	printf("-----------------------------------------------------\n");
	//system(“cls”)  可添加清屏选项
}
void help()
{
	printf("\n这是一个学生信息管理系统,为了帮助您更快的了解使用它,请先仔细阅读以下注意事项:\n");
	printf("\n                  注意事项:                    \n ");
	printf("\n       1、请根据提示进行操作!\n");
	printf("\n       2、初次使用请先选择增加学生信息!\n");
	printf("\n       3、修改或者增加学生信息后切记保存!\n");
	printf("\n       4、如果数据有错误,请先修改再保存!\n");
	printf("\n       5、若您之前使用过,下次进入系统请先刷新学生信息!\n");
	printf("\n       6、在添加学生时,用两个字符代表不同的性别,比如男用‘M’代替,女用‘W’代替!\n");
	printf("\n       7、保存或者刷新时,输入的文件名后缀请使用.txt,比如: stu.txt,系统会在源程序\n");
	printf("\n          “学生管理系统.exe”的相同目录建立一个.txt文件来保存学生信息,您可以查看\n");
	printf("\n          该文件,但非专业人员不要轻易改动,否则会造成刷新数据异常或刷新失败!\n");
	printf("\n       8、学生信息包括:姓名、学号、性别、年龄、C语言成绩、高数成绩、英语成绩等!\n");
	printf("\n       9、使用遇到任何问题请与我们联系,邮箱:13991770359@163.com\n");
	printf("\n       10、最后感谢您的使用!\n");
	system("pause");
}

void increase()
{
	int i = n, j, flag, m = 0;//i代表增加学生信息过程中任意时刻的学生人数 
	printf("\n请输入待增加的学生人数:\n");
	scanf("%d", &m);
	if (m > 0) {
		do {
			flag = 1;
			while (flag)
			{
				flag = 0;
				printf("请输入第%d位学生的学号:\n", i + 1);//第几位学生从1开始计数,而stu[]从零开始,需要加1 
				scanf("%s", stu[i].StuID);
				//判断学号是否重复
				for (j = 0; j < i; j++) 
				{
					if (strcmp(stu[i].StuID, stu[j].StuID) == 0) 
					{
						printf("该学号已经存在,请重新输入!\n");
						flag = 1;
						break;
					}
				}
			}
			printf("请输入第%d位学生姓名:\n", i + 1);
			scanf("%s", stu[i].Stuname);
			printf("请输入第%d位学生年龄:\n", i + 1);
			scanf("%d", &stu[i].Stuage);
			getchar();//处理上面输入的换行符,不然系统会把换行符当做一个字符赋值给性别 
			printf("请输入第%d位学生性别:\n", i + 1);
			scanf("%c", &stu[i].Stusex);
			printf("请输入第%d位学生的C语言成绩:\n", i + 1);
			scanf("%f", &stu[i].score[0]);
			printf("请输入第%d位学生的高数成绩:\n", i + 1);
			scanf("%f", &stu[i].score[1]);
			printf("请输入第%d位学生的大学英语成绩:\n", i + 1);
			scanf("%f", &stu[i].score[2]);
			i++;
		} while (i < n + m);//只要当前学生人数还没到达添加后的总人数,就得继续添加		
	}
	n += m;// 添加完成,系统人数n的值也要增加 
	printf("添加完成!!!\n");
	system("pause");
}
void seek()
{
	int i, num, flag;
	char s1[LEN + 1];
	printf("*****************************\n");
	printf("**-------1.按学号查询------**\n");
	printf("**-------2.按姓名查询------**\n");
	printf("**-------3.退出本菜单------**\n");
	printf("*****************************\n");
	while (1)
	{
		flag = 0;
		printf("请输入子菜单:");
		scanf("%d", &num);
		switch (num)
		{
		case 1:
			printf("请输入需要查找学生的学号:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].StuID, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 2:
			printf("请输入需要查找学生的姓名:\n");
			scanf("%s", s1);
			for (i = 0; i < n; i++)
			{
				if (strcmp(stu[i].Stuname, s1) == 0)
				{
					flag = 1;
					printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
					printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
				}
			}break;
		case 3: return;
		default: printf("请在1--3之间输入\n");
		}
		if (flag == 0)
			printf("找不到该学生!\n请重新输入!");
	}
}
void de()
{
	int i, j, flag;
	char s1[LEN];
	printf("请输入需要删除的学生学号:\n");
	scanf("%s", s1);
	flag = 0;
	for (i = 0; i < n; i++)
	{
		if (strcmp(s1, stu[i].StuID) == 0)
		{
			flag = 1;
			for (j = i; j < n - 1; j++)
			{
				stu[j] = stu[j + 1];//直接把后面的学生都往前移动一位 
			}
		}
		if (flag == 1) break;//说明已经找到了需要删除的学生,结束循环 
	}
	if (0 == flag)
	{
		printf("该学号不存在!!!\n");
	}

	if (1 == flag)
	{
		printf("删除成功\n");
		n--;
	}
	system("pause");
}

void save()//把学生信息保存到文件 
{
	int i;
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入要保存的文件名:\n");
	scanf("%s", filename);
	if ((fp = fopen(filename, "w")) == NULL)// “w” 以只读模式建立文本文件,若文件存在则文件长度清0
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	for (i = 0; i < n; i++)
		if (fwrite(&stu[i], sizeof(struct student), 1, fp) != 1)//云笔记记录
			printf("保存失败!!\n");
	printf("保存成功!!!\n");
	fclose(fp);
	system("pause");
}

void present()//展现出所有学生信息
{
	int i;

	if (n == 0)
	{
		printf("您好,现在没有学生信息,请先增加学生信息或者刷新再来试试!\n");
	}
	else
	{
		printf("现在共有%d名学生:\n", n);
		printf("学号\t\t姓名\t\t性别\t\t年龄\t\tC语言\t\t高数\t\t英语\n");
		for (i = 0; i < n; i++)
		{
			printf("%s\t\t%s\t\t%c\t\t%d\t\t%.2f\t\t%.2f\t\t%.2f\n", stu[i].StuID, stu[i].Stuname, stu[i].Stusex, stu[i].Stuage, stu[i].score[0], stu[i].score[1], stu[i].score[2]);
		}
	}

	system("pause");
}

void modify()//修改学生信息
{
	int i, flag;
	char ID[LEN], name[LEN], sex;
	int age;
	float score;
	printf("请输入需要修改的学生姓名:\n");
	getchar();//清除缓存中的回车,使gets正确读取
	gets(name);

	while (1)
	{
		flag = 0;
		for (i = 0; i < n; i++)
		{
			if (strcmp(name, stu[i].Stuname) == 0)//string.h
			{
				flag = 1;
				int num;//用于switch函数的子菜单 
				printf("***************************************************\n");
				printf("*----1.修改学号--------  -  -----2.修改性别-------*\n");
				printf("*----3.修改年龄--------  -  -----4.修改C语言成绩--*\n");
				printf("*----5.修改高数成绩----  -  -----6.修改英语成绩---*\n");
				printf("*-------------------7.退出本菜单------------------*\n");
				printf("***************************************************\n\n");
				printf("请输入子菜单:");
				scanf("%d", &num);
				switch (num)
				{
				case 1:
					printf("请输入新的学号:\n");
					getchar();
					gets(ID);
					strcpy(stu[i].StuID, ID); break;
				case 2:
					getchar();
					printf("请输入新的性别:\n");
					scanf("%c", &sex);
					stu[i].Stusex = sex; break;
				case 3:
					printf("请输入新的年龄:\n");
					scanf("%d", &age);
					stu[i].Stuage = age; break;
				case 4:
					printf("请输入新的C语言成绩:\n");
					scanf("%f", &score);
					stu[i].score[0] = score; break;
				case 5:
					printf("请输入新的高数成绩:\n");
					scanf("%f", &score);
					stu[i].score[1] = score; break;
				case 6:
					printf("请输入新的英语成绩:\n");
					scanf("%f", &score);
					stu[i].score[2] = score; break;
				case 7:
					return; break;
				default:
					printf("请在1--7之间选择!\n");
				}
				if (num > 0 && num < 7)
					printf("修改成功,记得保存哟!!!\n");
				break;//找到学生,结束循环;	
			}
		}
		if (flag == 0)
		{
			printf("没有找到该学生,请重新输入需要修改信息的学生姓名:\n");
			gets(name);
		}
	}
	system("pause");
}

void flush()//刷新
{
	int i, k = 0;//k代表刷新过程中学生人数 
	FILE* fp;
	char filename[LEN + 1];
	printf("请输入需要刷新的文件名:\n");
	getchar();               
	gets(filename);
	if ((fp = fopen(filename, "r")) == NULL)//打开文件 
	{
		printf("打开文件失败!\n");
		exit(0);//正常运行程序并退出程序;
	}
	for (i = 0; i < N; i++)//N是最大的学生人数,可在程序开头进行更改 
	{
		if (fread(&stu[i], sizeof(struct student), 1, fp) == 1)// “r” 代表以只读(只从文件读取数据)的方式打开文件
			k++;//记录学生人数 
	}
	n = k;// 把k的值给n													
	if (k == 0)
		printf("刷新失败!!!\n");
	else
		printf("刷新成功!!!\n");
	fclose(fp);
	system("pause");

}
void tuichu()
{
	int h;//控制是否确认退出 
	printf("即将退出,确认请按1,取消请按0\n");
	scanf("%d", &h);
	if (h == 1)
	{
		t = 0;//t是main函数中while函数是否继续执行的控制条件,是一个全局变量,程序开头已经定义并且赋值位 1
		printf("成功退出,感谢使用!\n");
	}
	if (h == 0)
	{
		printf("退出已取消!\n");
		system("pause");
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1417205.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA 学习 面试(十一)常见设计模式

设计模式 ## 1、创建型模式 对象实例化的模式&#xff0c;创建型模式用于解耦对象的实例化过程。 单例模式&#xff1a;某个类智能有一个实例&#xff0c;提供一个全局的访问点。 工厂模式&#xff1a;一个工厂类根据传入的参量决定创建出哪一种产品类的实例。 抽象工厂模式&a…

Android学习之路(25) Theme和Style

1、官方详细解读 样式和主题背景 | Android 开发者 | Android Developers 2、应用场景 类似web设计中css样式。将应用设计的细节与界面的结构和行为分开。 样式style &#xff1a;应用于 单个 View 的外观。样式可以指定字体颜色、字号、背景颜色等属性 主题theme&…

OpenHarmony—不支持解构赋值

规则&#xff1a;arkts-no-destruct-assignment 级别&#xff1a;错误 ArkTS不支持解构赋值。可使用其他替代方法&#xff0c;例如&#xff0c;使用临时变量。 TypeScript let [one, two] [1, 2]; // 此处需要分号 [one, two] [two, one];let head, tail [head, ...tail]…

WordPress如何使用SQL实现一键关闭/开启评论功能(已有评论)

WordPress本人就自带评论功能&#xff0c;不过由于种种原因&#xff0c;有些站长不想开启评论功能&#xff0c;那么应该怎么实现一键关闭评论功能或开启评论功能呢&#xff1f;或者针对已有评论功能的文章进行一键关闭或开启评论功能应该怎么操作&#xff1f; 如果你使用的Wor…

每日一道面试题:Java中序列化与反序列化

写在开头 哈喽大家好&#xff0c;在高铁上码字的感觉是真不爽啊&#xff0c;小桌板又拥挤&#xff0c;旁边的小朋友也比较的吵闹&#xff0c;影响思绪&#xff0c;但这丝毫不影响咱学习的劲头&#xff01;哈哈哈&#xff0c;在这喧哗的车厢中&#xff0c;思考着这样的一个问题…

Spring - 基本用法参考

Spring 官方文档 Spring容器启动流程&#xff08;源码解读&#xff09; BeanFactoryPostProcessor vs BeanPostProcessor vs BeanDefinitionRegistryPostProcessor&#xff1a; From java doc&#xff1a; BeanFactoryPostProcessor may interact with and modify bean defin…

MyBatis 如何整合 Druid 连接池?

Mybatis 如何整合 Druid 数据连接池呢&#xff1f;首先打开创建的 Maven 工程&#xff0c;找到 pom.xml 文件&#xff0c;添加 Druid 依赖。 <!--druid连接池--> <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId&…

Mac思维导图软件XMind for mac 中文版

XMind for Mac是一款高效、易于使用的思维导图软件&#xff0c;能够帮助用户更好地组织思维和创意。无论您需要制作工作报告、演讲稿还是学习笔记&#xff0c;XMind都能够为您提供卓越的支持和帮助。 软件下载&#xff1a;XMind for mac 中文版下载 XMind for Mac具有直观的界面…

精通Python第18篇—数据之美:Pyecharts水球图绘制与交互的完整教程

Pyecharts水球图绘制与交互的完整教程 在数据可视化领域&#xff0c;Pyecharts是一个强大而灵活的工具&#xff0c;它能够以美观的方式呈现各种图表&#xff0c;其中之一就是炫酷水球图。水球图能够生动地展示数据的比例关系&#xff0c;给用户一种直观的感受。本文将深入介绍…

爬虫基础-计算机网络协议

一个数据的传输 这些设备的数据转发是通过协议来完成的&#xff0c;整个互联网可以说是完全由网络协议来维持的 不同的协议分工不同&#xff0c;比如ip协议确保了ip寻址&#xff0c;tcp协议确保了数据完整性 IP地址和URL ip地址 整个网络传输可以比作快递&#xff0c;数据就…

C51 单片机学习(一):基础外设

参考 51单片机入门教程 1. 单片机简介 1.1 定义 单片机&#xff08;Micro Controller Unit&#xff0c;简称 MCU&#xff09; 内部集成了 CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能单片机的任务是信息采集&#xff08;依靠传感器&#xff09;、处…

【Spark系列2】Spark编程模型RDD

RDD概述 RDD最初的概述来源于一片论文-伯克利实验室的Resilient Distributed Datasets&#xff1a;A Fault-Tolerant Abstraction for In-Memory Cluster Computing。这篇论文奠定了RDD基本功能的思想 RDD实际为Resilient Distribution Datasets的简称&#xff0c;意为弹性分…

Linux提权:Docker组挂载 Rsync未授权 Sudo-CVE Polkit-CVE

目录 Rsync未授权访问 docker组挂载 Sudo-CVE漏洞 Polkit-CVE漏洞 这里的提权手法是需要有一个普通用户的权限&#xff0c;一般情况下取得的webshell权限可能不够 Rsync未授权访问 Rsync是linux下一款数据备份工具&#xff0c;默认开启873端口 https://vulhub.org/#/envir…

Linux:共享内存

文章目录 System V共享内存的原理管理共享内存shmgetshmatshmdtshmctl 共享内存和管道实现进程间同步通信 前面介绍完了匿名管道和命名管道&#xff0c;那么本篇要引入的主题是共享内存 System V 作为进程通信部分的内容&#xff0c;共享内存必然有其存在的意义和价值&#x…

RabbitMQ快速实战

目录 什么是消息队列&#xff1f; 消息队列的优势 应用解耦 异步提速 削峰填谷 总结 主流MQ产品特点比较 Rabbitmq快速上手 创建用户admin Exchange和Queue Connection和Channel RabbitMQ中的核心概念总结 什么是消息队列&#xff1f; MQ全称Message Queue&#xf…

从零学习Linux操作系统 第二十二部分 企业域名解析服务的部署及安全优化

# 一、dns的主要信息 关于dns的名词解释&#xff1a;dns: domain name service(域名解析服务) 关于客户端: /etc/resolv.conf dns指向文件 A记录 ##ip地址叫做域名的Address 记录 SOA ##授权起始主机 关于服务端 bind安装包named服务名称/etc/named.conf主配置文件/var/na…

【深度学习:多关节嵌入模型】 Meta 解释的 ImageBind 多关节嵌入模型

【深度学习&#xff1a;多关节嵌入模型】 Meta 解释的 ImageBind 多关节嵌入模型 Meta 发布开源人工智能工具的历史分段任何模型DINOv2 什么是多模态学习&#xff1f;什么是嵌入&#xff1f;什么是 ImageBind&#xff1f;集成在 ImageBind 中的模式图像绑定架构特定模式编码器跨…

window下如何安装ffmpeg(跨平台多媒体处理工具)

ffmpeg是什么? FFmpeg是一个开源的跨平台多媒体处理工具&#xff0c;可以用于录制、转换和流媒体处理音视频。它包含了几个核心库和工具&#xff0c;可以在命令行下执行各种音视频处理操作&#xff0c;如剪辑、分割、合并、媒体格式转换、编解码、流媒体传输等。FFmpeg支持多…

java设计模式:工厂模式

1&#xff1a;在平常的开发工作中&#xff0c;我们可能会用到不同的设计模式&#xff0c;合理的使用设计模式&#xff0c;可以提高开发效率&#xff0c;提高代码质量&#xff0c;提高系统的可拓展性&#xff0c;今天来简单聊聊工厂模式。 2&#xff1a;工厂模式是一种创建对象的…

Java TemporalAdjusters 时间调节器

提供了非常多处理日期相关的函数&#xff1a; 使用示例&#xff1a; /*** JCccc* param args*/public static void main(String[] args) {DateTimeFormatter pattern DateTimeFormatter.ofPattern("yyyy-MM-dd");LocalDateTime now LocalDateTime.now();//获取当月…