C语言实现课堂随机点名系统

今天重温一下在学校时写的课程设计,复习一下在学校里学到的东西,同时也希望能够帮助到那些和我一样被课设所折磨的可怜人儿~

1、项目要求

课堂随机点名程序
要求能完全实现我们的点名程序已有的功能。即事先从教务处网站上下载某班的学生名单并存盘备用。你的程序能够以某种方式有选择性的加载某个班的存盘文件并把相应的学生信息读入内存,然后以随机的方式来查找某个学生的信息并把它显示出来以实现点名。

2、项目功能的实现

要想比较完整地实现一个点名系统,除了最基本的随机点名,还需要增加、删除、修改等功能,这就需要我们通过思考后,用函数的方式将它们实现。以下,就是我在这个项目中所用到的函数。

先看一下项目的软件结构图






首先定义一个结构体,由于只是用于课堂点名,因此这里结构体中学生的信息只包含学号与姓名。

typedef struct StuInfo
{
	int id;
    char name[MAX];
}StuInfo;

函数一:将选择打开文件内容读入结构体中
//将文件内容读入结构体中
void stu_open(char* file, FILE* fp,StuInfo* s,int num)
{
	int i = 0;
	fscanf(fp, "%d", &num);//读入班级人数
	for (i = 0; i < num; i++)
	{
		fscanf(fp, "%d %s", &(s[i].id), s[i].name);//循环读入每个学生的信息
	}
	return;
}

这里传参时,file是选择打开的文件,s为创建的结构体数组,num为班级人数,这些在后面完整代码中都会呈现,由于这里是解释具体的代码内容,因此没有体现出具体的创建过程。后面函数的传参与其相同。



函数二:随机点名函数
//随机点名
void stu_byname(char* file,StuInfo* s,int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int i = 0;
	i = rand() % num;//得到班级人数内的随机数
	printf("\n学号:  %d\n姓名:  %s\n", s[i].id, s[i].name);//将该随机数对应学生信息打印显示出来
}

在主函数中已经设置了随机数生成器:srand((unsigned int)time(NULL)),因此这里只需要直接用rand()得到随机数。

这里顺便解释一下随机数是如何得到的:
srand为设置一个随机数种子,为防止每次产生的随机数重复,因此需要设定不同的随机数种子,又时间每时每刻都在改变,因此我们就可以以时间戳来作为随机数种子,以此来产生不同的随机数。time函数可以生成当前时间的时间戳,其标准形式为 time_t time (time_t* timer),其参数为一个指针,我们只需要调用time函数,故可以将参数直接写为NULL,time的返回类型为time_t,而srand需要的为整数,因此我们还需要将其强制类型转换为unsigned int ,这就组成了我们最终的随机数生成器:srand((unsigned int)time(NULL)),在之后生成随机数时,就只需要调用rand()函数即可。

时间戳:
在这里插入图片描述

函数三:添加学生信息
//添加学生信息
void stu_add(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int i = 0;
	int j = 0;
	int m = 0;
	char str[20] = { 0 };
	printf("请输入添加学生的学号和姓名:>");
	scanf("%d  %s", &m, &str);

	//判断该学号是否已经存在
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			printf("该学号已存在!\n");
			printf("添加失败!\n");
			break;
		}
	}

	//若不存在,则对该学生进行添加
	if (i == num)
	{
		num = num + 1;
		//重置文件指针到文件开头,并重新写入班级人数
		rewind(fp);
		fprintf(fp, "%d", num);
		//将文件指针移至文件末尾,写入新添加的学生
		fseek(fp, 0, SEEK_END);
		fprintf(fp, "\n%d %s", m, str);
		printf("添加成功\n");
	}
}

函数四:删除学生信息
//删除学生信息
void stu_del(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	stu_close(file, fp);
	//关闭该文件,并重新以"w+"的方式打开该文件
	FILE* ffp = fopen(file, "w+");
	int input = 0;
	int k = 0;
	do
	{
		menu_del();
		printf("请输入删除方式:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			stu_del_id(file, fp,s,num);
			break;
		case 2:
			stu_del_name(file, fp,s,num);
			break;
	    //由于是以"w+"的方式打开的文件,里面的内容会被清空,因此,若取消或退出删除,需要将结构体的内容再写入文件中
		case 0:
			fprintf(ffp, "%d\n", num);
			for (k = 0; k < num; k++)
			{
				fprintf(ffp, "%d %s", s[k].id, s[k].name);
				if (k < num - 1)
				{
					fputc('\n', ffp);
				}
			}
			printf("退出删除!\n");
			break;
		default:
			rewind(ffp);
			fprintf(ffp, "%d\n", num);
			for (k = 0; k < num; k++)
			{
				fprintf(ffp, "%d %s", s[k].id, s[k].name);
				if (k < num - 1)
				{
					fputc('\n', ffp);
				}
			}
			printf("输入错误!请重新输入!\n");
			break;
		}
		stu_close(file, ffp);
	} while (input);
}

这里提供了两种删除方式:按学号删除和按姓名删除(下面的查询、修改、排序等也都是包含了这两种方式),并有确认删除等操作,进一步完善了代码的功能。接下来就是两种删除方式的具体代码:

//按学号删除
void stu_del_id(char* file, FILE* fp,StuInfo* s,int num)
{
	int m = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	int flag = 0;
	
	printf("请输入要删除的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			//确认是否删除
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			printf("您确定要删除这位学生的信息吗?(0/1):>");
			scanf("%d", &flag);
			switch (flag)
			{
			case 1:
				for (j = i; j < num; j++)
				{
					s[j] = s[j + 1];
				}
				num--;
				//重置文件指针到文件开头,并重新写入班级人数
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (k = 0; k < num; k++)
				{
					fprintf(fp, "%d %s", s[k].id, s[k].name);
					if (k < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("删除成功!\n");
				break;
			case 0:
				printf("操作成功!取消删除,返回上级菜单!\n");
				break;
			default:
				printf("输入错误!请重新输入:>\n");
				break;
			}
			break;
		}
	}
	if (i == num)
	{
		printf("该学号不存在!\n");
		printf("删除失败!\n");
	}
}
//按姓名删除
void stu_del_name(char* file, FILE* fp,StuInfo* s,int num)
{
	int i = 0;
	int j = 0;
	int k = 0;
	int flag = 0;
	char str[20] = { 0 };
	//fscanf(fp, "%d\n", &num);
	//stu_open(file, fp, s, num);
	printf("请输入要删除的姓名:>");
	scanf("%s", &str);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s[i].name, str) == 0)
		{
			//确认是否删除
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			printf("您确定要删除这位学生的信息吗?(0/1):>");
			scanf("%d", &flag);
			switch (flag)
			{
			case 1:
				for (j = i; j < num; j++)
				{
					s[j] = s[j + 1];
				}
				num--;
				//重置文件指针到文件开头,并重新写入班级人数
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (k = 0; k < num; k++)
				{
					fprintf(fp, "%d %s", s[k].id, s[k].name);
					if (k < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("删除成功!\n");
				break;
			case 0:
				printf("操作成功!取消删除,返回上级菜单!\n");
				break;
			default:
				printf("输入错误!请重新输入:>\n");
				break;
			}
			break;
		}
	}
	if (i == num)
	{
		printf("该姓名不存在!\n");
		printf("删除失败!\n");
	}
}

两种删除方式总体的思路相同,都是先具体查找到该学生的信息并打印,再确认是否删除,确认删除后,用后面学生的信息逐一向上覆盖,并将班级人数减一,以达到删除信息的效果。

函数五:查询学生信息
//查询信息
void stu_located(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int input = 0;
	do
	{
		menu_located();
		printf("请选择查询方式:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			located_id(s,num);
			break;
		case 2:
			located_name(s,num);
			break;
		case 0:
		    printf("取消查询!\n");
			break;
		default:
			printf("输入错误!请重新输入:>\n");
			break;
		}
	} while (input);
}
//按学号查询
void located_id(StuInfo* s, int num)
{
	int m = 0;
	int i = 0;
	printf("请输入要查询的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			//查询成功,输出该学生信息
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			break;
		}
	}
	if (i == num)
	{
		printf("该学号不存在!\n");
	}
}
//按姓名查询
void located_name(StuInfo* s, int num)
{

	char s1[MAX];
	int i = 0;
	int j = 0;

	printf("请输入要查询的姓名:>");
	scanf("%s", &s1);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s1, s[i].name) == 0)
		{
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			break;
		}
	}
	if (i == num)
	{
		printf("该姓名不存在!\n");
	}
}

函数六:修改学生信息
//修改学生信息
void stu_multify(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int input = 0;
	do
	{
		menu_multify();
		printf("请选择修改方式:>");
		scanf("%d", &input);
	switch (input)
		{
		case 1:
			multify_id(file, fp,s,num);
			break;
		case 2:
			multify_name(file, fp,s,num);
			break;
		case 0:
		    printf("取消修改!\n");
			break;
		default:
			printf("输入错误!请重新输入:>\n");
			break;
		}
	} while (input);
}
//输入学号进行修改
void multify_id(char* file, FILE* fp, StuInfo* s, int num)
{
	char s1[20] = { 0 };
	int i = 0;
	int j = 0;
	int k = 0;
	int m = 0;
	int n = 0;
	printf("请输入要修改学生的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			printf("当前学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			printf("请输入修改后的学号:>");
			scanf("%d", &n);

			//判断修改后的学号是否已存在
			for (k = 0; k < num; k++)
			{
				if (n == s[k].id)
				{
					printf("该学号已存在!\n");
					printf("该学号学生姓名为:>%s\n", s[k].name);
					break;
				}
			}
			if (k == num)
			{
				s[i].id = n;
				printf("修改后该学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (j = 0; j < num; j++)
				{
					fprintf(fp, "%d %s", s[j].id, s[j].name);
					if (j < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("修改成功!\n");
				break;
			}
		}
	}
	if (i > num)
	{
		printf("该学号不存在!\n");
		printf("修改失败!\n");
	}
}
//输入姓名进行修改
void multify_name(char* file, FILE* fp, StuInfo* s, int num)
{
	char s1[20] = { 0 };
	char s2[20] = { 0 };
	int i = 0;
	int j = 0;
	int k = 0;
	int m = 0;
	printf("请输入要修改学生的姓名:>");
	scanf("%s", &s1);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s1, s[i].name) == 0)
		{
			printf("当前学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			printf("请输入修改后的姓名:>");
			scanf("%s", s1);
			strcpy(s[i].name, s1);
			printf("修改后该学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			rewind(fp);
			fprintf(fp, "%d\n", num);
			for (j = 0; j < num; j++)
			{
				fprintf(fp, "%d %s", s[j].id, s[j].name);
				if (j < num - 1)
				{
					fputc('\n', fp);
				}
			}
			printf("修改成功!\n");
			break;
		}
	}
	if (i > num)
	{
		printf("该姓名不存在!\n");
		printf("修改失败!\n");
	}
}

函数七:展示学生信息
//展示学生信息
void stu_show(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d\n", &num);
	int i = 0;
	printf("该班级学生信息为:\n");
	printf("学号    姓名\n");
	for (i = 0; i < num; i++)
	{
		printf("%d    %s\n", s[i].id, s[i].name);
	}
}

这里通过循环,将所有学生的信息打印显示出来。

函数八:排序学生信息
//排序学生信息
void stu_sort(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d\n", &num);
	int i = 0;
	int input = 0;
	menu_sort();
	printf("请选择排序方式:>");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(s, num, sizeof(s[0]), cmp_by_id);
		printf("排序完成!\n");
		break;
	case 2:
		qsort(s, num, sizeof(s[0]), cmp_by_name);
		printf("排序完成!\n");
		break;
	case 0:
		printf("取消排序!\n");
		break;
	default:
		printf("输入错误!请重新输入:>\n");
		break;
	}

	rewind(fp);
	fprintf(fp, "%d\n", num);
	for (i = 0; i < num; i++)
	{
		fprintf(fp, "%d %s", s[i].id, s[i].name);
		if (i < num - 1)
		{
			fputc('\n', fp);
		}
	}
}
//按学号排序
int cmp_by_id(const void* e1, const void* e2)
{
	//e1、e2为void*类型,先将其强制性类型转换为结构体(StuInfo*)类型,再指向id进行比较
	return (((StuInfo*)e1)->id - ((StuInfo*)e2)->id);
}
//按姓名排序
int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((StuInfo*)e1)->name, ((StuInfo*)e2)->name);
}

这里排序方法我用的是qsort函数

void qsort
(
void* base,//待排序数组的首地址
size_t num,//待排序数组的元素个数
size_t width,//待排序数组每个元素的大小(以字节为单位)
int (* cmp)(const void* e1,const void* e2)//函数指针,比较两个元素时所用函数的地址(该函数要自己实现),里面的两个参数为要比较的两个元素的地址
)

qsort函数内部有四个参数,这里它们的意义都已经一一列举出来了。注意实现最后一个函数时,参数类型一定为const void*

3、项目演示

1.展示

(由于功能都是在已有的班级文件的基础上进行,因此,这里我先展示班级学生信息。)
展示

2.点名

点名

3.增添

增加


4.删除

删除


5.查找

查询

6.修改

修改

7.排序

排序·1


排序2

4、代码展示

1. byname.h

(包含宏的定义、头文件的引用以及函数的声明和结构体的创建)
不要忘记在后面两个文件中都要引用这个头文件

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <errno.h>

#define MAX 100

//创建一个结构体
typedef struct StuInfo
{
	int id;
	char name[MAX];
}StuInfo;

void stu_open(char* file, FILE* fp,StuInfo* s,int num);
void stu_byname(char* file,StuInfo* s,int num);
void stu_add(char* file,StuInfo* s,int num);
void stu_del(char* file,StuInfo* s,int num);
void stu_located(char* file,StuInfo* s,int num);
void stu_show(char* file,StuInfo* s,int num);
void stu_multify(char* file,StuInfo* s,int num);
void stu_sort(char* file,StuInfo* s,int num);
void stu_close(char* file, FILE* fp);

2. byname.c

(包含各种功能函数的实现)

#define _CRT_SECURE_NO_WARNINGS 1

#include "byname.h"

//将文件内容读入结构体中
void stu_open(char* file, FILE* fp,StuInfo* s,int num)
{
	int i = 0;
	//stu_write(file, fp, count);
	fscanf(fp, "%d", &num);
	for (i = 0; i < num; i++)
	{
		fscanf(fp, "%d %s", &(s[i].id), s[i].name);
	}
	return;
}

//随机点名
void stu_byname(char* file,StuInfo* s,int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	//stu_open(file, fp, s, num);
	int i = 0;
	//得到随机数
	i = rand() % num;
	printf("\n学号:  %d\n姓名:  %s\n", s[i].id, s[i].name);
}

//添加学生信息
void stu_add(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int i = 0;
	int j = 0;
	int m = 0;
	char str[20] = { 0 };
	printf("请输入添加学生的学号和姓名:>");
	scanf("%d  %s", &m, &str);

	//判断该学号是否已经存在
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			printf("该学号已存在!\n");
			printf("添加失败!\n");
			break;
		}
	}

	//若不存在,则对该学生进行添加
	if (i == num)
	{
		num = num + 1;
		//重置文件指针到文件开头,并重新写入班级人数
		rewind(fp);
		fprintf(fp, "%d", num);
		//将文件指针移至文件末尾,写入新添加的学生
		fseek(fp, 0, SEEK_END);
		fprintf(fp, "\n%d %s", m, str);
		printf("添加成功\n");
	}
}

//删除菜单
void menu_del()
{
	printf("*********************************\n");
	printf("*********  1.按学号删除 *********\n");
	printf("*********  2.按姓名删除 *********\n");
	printf("*********   0.取消删除  *********\n");
	printf("*********************************\n");
}

//按学号删除
void stu_del_id(char* file, FILE* fp,StuInfo* s,int num)
{
	int m = 0;
	int i = 0;
	int j = 0;
	int k = 0;
	int flag = 0;
	
	printf("请输入要删除的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			//确认是否删除
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			printf("您确定要删除这位学生的信息吗?(0/1):>");
			scanf("%d", &flag);
			switch (flag)
			{
			case 1:
				for (j = i; j < num; j++)
				{
					s[j] = s[j + 1];
				}
				num--;
				//重置文件指针到文件开头,并重新写入班级人数
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (k = 0; k < num; k++)
				{
					fprintf(fp, "%d %s", s[k].id, s[k].name);
					if (k < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("删除成功!\n");
				break;
			case 0:
				printf("操作成功!取消删除,返回上级菜单!\n");
				break;
			default:
				printf("输入错误!请重新输入:>\n");
				break;
			}
			break;
		}
	}
	if (i == num)
	{
		printf("该学号不存在!\n");
		printf("删除失败!\n");
	}

}

//按姓名删除
void stu_del_name(char* file, FILE* fp,StuInfo* s,int num)
{
	int i = 0;
	int j = 0;
	int k = 0;
	int flag = 0;
	char str[20] = { 0 };
	//fscanf(fp, "%d\n", &num);
	//stu_open(file, fp, s, num);
	printf("请输入要删除的姓名:>");
	scanf("%s", &str);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s[i].name, str) == 0)
		{
			//确认是否删除
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			printf("您确定要删除这位学生的信息吗?(0/1):>");
			scanf("%d", &flag);
			switch (flag)
			{
			case 1:
				for (j = i; j < num; j++)
				{
					s[j] = s[j + 1];
				}
				num--;
				//重置文件指针到文件开头,并重新写入班级人数
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (k = 0; k < num; k++)
				{
					fprintf(fp, "%d %s", s[k].id, s[k].name);
					if (k < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("删除成功!\n");
				break;
			case 0:
				printf("操作成功!取消删除,返回上级菜单!\n");
				break;
			default:
				printf("输入错误!请重新输入:>\n");
				break;
			}
			break;
		}
	}
	if (i == num)
	{
		printf("该姓名不存在!\n");
		printf("删除失败!\n");
	}
}

//删除学生信息
void stu_del(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	stu_close(file, fp);
	//关闭该文件,并重新以"w+"的方式打开该文件
	FILE* ffp = fopen(file, "w+");
	int input = 0;
	int k = 0;
	do
	{
		menu_del();
		printf("请输入删除方式:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			stu_del_id(file, fp,s,num);
			break;
		case 2:
			stu_del_name(file, fp,s,num);
			break;
	    //由于是以"w+"的方式打开的文件,里面的内容会被清空,因此,若取消或退出删除,需要将结构体的内容再写入文件中
		case 0:
			fprintf(ffp, "%d\n", num);
			for (k = 0; k < num; k++)
			{
				fprintf(ffp, "%d %s", s[k].id, s[k].name);
				if (k < num - 1)
				{
					fputc('\n', ffp);
				}
			}
			printf("退出删除!\n");
			break;
		default:
			rewind(ffp);
			fprintf(ffp, "%d\n", num);
			for (k = 0; k < num; k++)
			{
				fprintf(ffp, "%d %s", s[k].id, s[k].name);
				if (k < num - 1)
				{
					fputc('\n', ffp);
				}
			}
			printf("输入错误!请重新输入!\n");
			break;
		}
		stu_close(file, ffp);
	} while (input);
}

//查询菜单
void menu_located()
{
	printf("--------------------------\n");
	printf("-------1.按学号查询-------\n");
	printf("-------2.按姓名查询-------\n");
	printf("-------0.退出查询---------\n");
	printf("--------------------------\n");
}

//按学号查询
void located_id(StuInfo* s, int num)
{
	int m = 0;
	int i = 0;
	printf("请输入要查询的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			//查询成功,输出该学生信息
			printf("该学生信息为:\n");
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			break;
		}
	}
	if (i == num)
	{
		printf("该学号不存在!\n");
	}
}

//按姓名查询
void located_name(StuInfo* s, int num)
{

	char s1[MAX];
	int i = 0;
	int j = 0;

	printf("请输入要查询的姓名:>");
	scanf("%s", &s1);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s1, s[i].name) == 0)
		{
			printf("学号:>%d    姓名:>%s\n", s[i].id, s[i].name);
			break;
		}
	}
	if (i == num)
	{
		printf("该姓名不存在!\n");
	}
}

//查询信息
void stu_located(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int input = 0;
	do
	{
		menu_located();
		printf("请选择查询方式:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			located_id(s,num);
			break;
		case 2:
			located_name(s,num);
			break;
		case 0:
			break;
		default:
			printf("输入错误!请重新输入:>\n");
			break;
		}
	} while (input);
}

//修改菜单
void menu_multify()
{
	printf("*******************************\n");
	printf("*********  1.修改学号 *********\n");
	printf("*********  2.修改姓名 *********\n");
	printf("*********  0.取消修改 *********\n");
	printf("*******************************\n");
}

//输入学号进行修改
void multify_id(char* file, FILE* fp, StuInfo* s, int num)
{
	//fscanf(fp, "%d", &num);
	char s1[20] = { 0 };
	int i = 0;
	int j = 0;
	int k = 0;
	int m = 0;
	int n = 0;
	printf("请输入要修改学生的学号:>");
	scanf("%d", &m);
	for (i = 0; i < num; i++)
	{
		if (m == s[i].id)
		{
			printf("当前学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			printf("请输入修改后的学号:>");
			scanf("%d", &n);

			//判断修改后的学号是否已存在
			for (k = 0; k < num; k++)
			{
				if (n == s[k].id)
				{
					printf("该学号已存在!\n");
					printf("该学号学生姓名为:>%s\n", s[k].name);
					break;
				}
			}
			if (k == num)
			{
				s[i].id = n;
				printf("修改后该学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
				rewind(fp);
				fprintf(fp, "%d\n", num);
				for (j = 0; j < num; j++)
				{
					fprintf(fp, "%d %s", s[j].id, s[j].name);
					if (j < num - 1)
					{
						fputc('\n', fp);
					}
				}
				printf("修改成功!\n");
				break;
			}
		}
	}
	if (i > num)
	{
		printf("该学号不存在!\n");
		printf("修改失败!\n");
	}
}

//输入姓名进行修改
void multify_name(char* file, FILE* fp, StuInfo* s, int num)
{
	//fscanf(fp, "%d", &num);
	char s1[20] = { 0 };
	char s2[20] = { 0 };
	int i = 0;
	int j = 0;
	int k = 0;
	int m = 0;
	printf("请输入要修改学生的姓名:>");
	scanf("%s", &s1);
	for (i = 0; i < num; i++)
	{
		if (strcmp(s1, s[i].name) == 0)
		{
			printf("当前学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			printf("请输入修改后的姓名:>");
			scanf("%s", s1);
			strcpy(s[i].name, s1);
			printf("修改后该学生的学号为:>%d    姓名为:>%s\n", s[i].id, s[i].name);
			rewind(fp);
			fprintf(fp, "%d\n", num);
			for (j = 0; j < num; j++)
			{
				fprintf(fp, "%d %s", s[j].id, s[j].name);
				if (j < num - 1)
				{
					fputc('\n', fp);
				}
			}
			printf("修改成功!\n");
			break;
		}
	}
	if (i > num)
	{
		printf("该姓名不存在!\n");
		printf("修改失败!\n");
	}
}

//修改学生信息
void stu_multify(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d", &num);
	int input = 0;
	do
	{
		menu_multify();
		printf("请选择修改方式:>");
		scanf("%d", &input);
	switch (input)
		{
		case 1:
			multify_id(file, fp,s,num);
			break;
		case 2:
			multify_name(file, fp,s,num);
			break;
		case 0:
			break;
		default:
			printf("输入错误!请重新输入:>\n");
			break;
		}
	} while (input);

}

//展示学生信息
void stu_show(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d\n", &num);
	int i = 0;
	printf("该班级学生信息为:\n");
	printf("学号    姓名\n");
	for (i = 0; i < num; i++)
	{
		printf("%d    %s\n", s[i].id, s[i].name);
	}
}

//排序菜单
void menu_sort()
{
	printf("***********************************\n");
	printf("********** 1.按学号排序 ***********\n");
	printf("********** 2.按姓名排序 ***********\n");
	printf("**********  0.取消排序  ***********\n");
	printf("***********************************\n");
}

qsort函数
//void qsort
// (
//	void* base,//待排序数组的首地址
//	size_t num,//待排序数组的元素个数
//	size_t width,//待排序数组每个元素的大小(以字节为单位)
//	int (*cmp)(const void* e1,const void* e2)//函数指针,比较两个元素时所用函数的地址(该函数要自己实现),里面
// )                                        //的两个参数为要比较的两个元素的地址

//按学号排序
int cmp_by_id(const void* e1, const void* e2)
{
	//e1、e2为void*类型,先将其强制性类型转换为结构体(StuInfo*)类型,再指向id进行比较
	return (((StuInfo*)e1)->id - ((StuInfo*)e2)->id);
}

//按姓名排序
int cmp_by_name(const void* e1, const void* e2)
{
	return strcmp(((StuInfo*)e1)->name, ((StuInfo*)e2)->name);
}

//排序学生信息
void stu_sort(char* file, StuInfo* s, int num)
{
	FILE* fp = fopen(file, "r+");
	fscanf(fp, "%d\n", &num);
	int i = 0;
	int input = 0;
	menu_sort();
	printf("请选择排序方式:>");
	scanf("%d", &input);
	switch (input)
	{
	case 1:
		qsort(s, num, sizeof(s[0]), cmp_by_id);
		break;
	case 2:
		qsort(s, num, sizeof(s[0]), cmp_by_name);
		break;
	case 0:
		printf("取消排序!\n");
		break;
	default:
		printf("输入错误!请重新输入:>\n");
		break;
	}

	printf("排序完成!\n");
	rewind(fp);
	fprintf(fp, "%d\n", num);
	for (i = 0; i < num; i++)
	{
		fprintf(fp, "%d %s", s[i].id, s[i].name);
		if (i < num - 1)
		{
			fputc('\n', fp);
		}
	}
}

//关闭文件
void stu_close(char* file, FILE* fp)
{
	fclose(fp);
	fp = NULL;
}

3.test.c

(包含了主函数,以及前两份文件的代码)

#define _CRT_SECURE_NO_WARNINGS 1
#include "byname.h"

void menu()
{
	printf("*****************************************************\n");
	printf("*************    1.开始点名    2.增添   *************\n");
	printf("*************    3.删除        4.查找   *************\n");
	printf("*************    5.修改        6.显示   *************\n");
	printf("*************    7.排序        0.退出   *************\n");
	printf("*****************************************************\n");
}

void test()
{
	StuInfo s[MAX] = { 0 };//学生数组
	int num = 0;//班级人数
	char file[32];
	printf("请输入要打开的班级文件:>");
	scanf("%s", &file);
	FILE* fp;
	fp = fopen(file, "r+");

	//若打开失败,则打印“Open Failed!”,并显示打开失败的原因
	if (fp == NULL)
	{
		printf("Open Failed: % s\n", strerror(errno));
		return;
	}
	//将文件以"r+"的方式打开并将其内容写入结构体中,再关闭该文件,后面再以各功能需要的方式打开文件
	stu_open(file, fp, s, num);
	stu_close(file, fp);

	int input = 0;
	do
	{
		menu();
		printf("请输入您的选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			stu_byname(file,s,num);
			break;
		case 2:
			stu_add(file,s,num);
			break;
		case 3:
			stu_del(file,s,num);
			break;
		case 4:
			stu_located(file,s,num);
			break;
		case 5:
			stu_multify(file,s,num);
			break;
		case 6:
			stu_show(file,s,num);
			break;
		case 7:
			stu_sort(file,s,num);
			break;
		case 0:
			printf("即将退出!欢迎下次使用!\n");
			break;
		default:
			printf("输入错误!请重新输入:>\n");
			break;
		}
		stu_close(file, fp);
	} while (input);
}

int main()
{
	srand((unsigned int)time(NULL));
	test();
	return 0;
}

5、总结

第一次独立完成一个完整的项目,刚开始时却是有很大的难度,甚至认为自己不可能完成,但在“逼迫”中慢慢的摸索,最后竟也成功了。
今天用博客的方式将它展现出来,若有任何不妥的地方,请大家不吝赐教,我一定认真听取并及时改正!!!
在这里插入图片描述

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值