C语言_学生信息管理系统项目(文件版)代码

续接上次的文章C语言_学生信息管理系统项目心得今天把所有代码贴出来,复制即可用,本人用的vs2013。

自学c,花了一个星期的时间,采用最笨的方式(非链表),初步实现了文件版本的学生信息管理系统,运行后会自动生成txt文件,具备文件的增删改查功能。
##    代码很笨重(有很多重复的地方可以优化),但大多有注释。且存在诸多bug,但暂不影响目前功能的简单实现。
##     **已知的bug有:1、使用删除功能后,txt文件中会遗留已经删除的记录部分信息,一般就是几个字符的残留,但不影响对文件有效数据的再次读取;2、有时修改记录后再添加新记录会再重新读取数据后显示出乱码,但暂时应该不影响文件数据的实际操作;3、在输入数据时(采用的scanf函数)可以通过上下方向键来选取到之前输入的数据而无需再次输入(该问题弄了很久没搞清楚,尝试了几种清楚缓存流的方式,无果;个人感觉涉及到堆栈方面的知识)对以上已知的问题还有各位发现的问题,若有可行的解决办法或者思路还望留言告知,谢谢**
#

以下是详细代码:

.h文件

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


typedef struct _student{
	int id;				//学号
	char name[10];		//姓名
	int age;			//年龄
	double grade[4];	//分数(语数外)
	char sex[4];		//性别


}Student, *PStudent;

int TotalStudents;				//学生总数
int recnum;						//文件数据记录条数

void Initial();					//初始化
void SetPos(int x, int y);		//光标设置函数
void StartShow();				//开始界面
void AddStu();					//添加学生
void ShowAll();					//显示所有学生信息及统计
void table(int num);			//学生信息及成绩统计表框架
void DelStu();					//按学号删除学生数据
int FindStu();					//按学号查找学生
void ChangeMeg();				//按学号修改学生信息
int int_to_str(int n, char str[]);//int to string,返回字符个数含'\0'
int str_to_int(int totalstu, char str[][8][20], Student students[]);//将str中0-9字符转换为数值存储到students[],若为文字字符则不变,返回实际有效记录条数
void Deldata(int pianyishu, int len);		//从文件中删除数据记录:采用直接定位文件位置的方式
void saveMeg(Student *students);//从students[]中映射并保存新增的学生信息到文件
void ReadFileMeg();//读取文件信息
void Read_xuehao(int xuehao);//按学号读取文件信息
void Del_File_rec(int pianyi, int len, FILE *fp);//从文件删除一条记录
void Read_to_change(int xuehao, Student *students, int n);//修改文件中某条记录
void changetosave(Student *students, FILE *fp);//将修改信息保存到文件

main.c文件

#include "STU.h"

int main(){

	printf("版本1.2_2020-6-21\n");
	printf("简介:\n");
	printf("1、初步实现了增删改查基本功能\n");
	printf("问题:\n");
	printf("\t信息保存到文件以及从文件读取信息基本没问题,保存的文件名“mydata.txt”\n");
	printf("\t1、从文件中删除相应的记录以及修改相应的记录,会出现在文件中的定位问题,导致删除后的\n");
	printf("\t文件中有原记录的残留,但应该暂时不影响对文件数据的实际操作");
	printf("\t修改记录后再次添加新记录,会再显示全部信息时出现部分乱码,但应该不影响文件数据的实际操作\n");
	printf("\t\t\t\t系统准备中......\n");
	system("pause");
	system("cls");

	ReadFileMeg();
	Initial();
	printf("\n\n\n\n\n");


	return 0;
}

函数实现文件:

#include "STU.h"
extern int TotalStudents = 0;
extern int recdnum = 0;

enum Subjects{ english, chinses, math }subject;

Student students[100];
PStudent pstudent = NULL;


void AddStu(){//添加

	SetPos(5, 19);
	if (TotalStudents < 100){
		printf("添加学生数据:");
		SetPos(5, 19 + 1);	printf("姓名:");
		SetPos(5, 19 + 2);	printf("学号:");
		SetPos(5, 19 + 3);	printf("年龄:");
		SetPos(5, 19 + 4);	printf("语文:");
		SetPos(5, 19 + 5);	printf("数学:");
		SetPos(5, 19 + 6);	printf("英语:");
		SetPos(5, 19 + 7);	printf("性别:");

		SetPos(5 + 8, 19 + 1); scanf_s("%s", &students[TotalStudents].name, 10); fflush(stdin);
		if (TotalStudents > 0){
			int t = TotalStudents;//此时实际的学生数量
			while (t){//检查输入学号,还可继续优化
				SetPos(5 + 8, 19 + 2); scanf_s("%d", &students[TotalStudents].id); fflush(stdin);
				for (int i = 0; i < TotalStudents; i++){
					if (students[i].id != students[TotalStudents].id){
						t--;
					}
				}
				if (t != 0){
					SetPos(5 + 8, 19 + 2 + 6); printf("学号有重复,请重新输入!");
					t = TotalStudents;
				}
			}
			SetPos(5 + 8, 19 + 2 + 6); printf("                         ");
		}
		else{
			SetPos(5 + 8, 19 + 2); scanf_s("%d", &students[TotalStudents].id); fflush(stdin);
		}
		SetPos(5 + 8, 19 + 3); scanf_s("%d", &students[TotalStudents].age); fflush(stdin);
		SetPos(5 + 8, 19 + 4); scanf_s("%lf", &students[TotalStudents].grade[0]); fflush(stdin);//语文
		SetPos(5 + 8, 19 + 5); scanf_s("%lf", &students[TotalStudents].grade[1]); fflush(stdin);//数学
		SetPos(5 + 8, 19 + 6); scanf_s("%lf", &students[TotalStudents].grade[2]); fflush(stdin);//英语
		SetPos(5 + 8, 19 + 7); scanf_s("%s", &students[TotalStudents].sex, 4); fflush(stdin);
		students[TotalStudents].grade[3] = students[TotalStudents].grade[0] + students[TotalStudents].grade[1] + students[TotalStudents].grade[2];


		TotalStudents++;	//每添加成功一条学生信息,学生数量+1
		SetPos(5, 28);
		printf("添加成功!!!\n");
		system("pause");
		StartShow();
		/*int c;  在这里无效
		while ((c = getchar()) != '\n' && c != EOF);*/
	}
	else
		printf("学生名额已满,不能再继续添加!!!");
	//将新增数据映射保存到文件
	Student *p = NULL;
	p = &students[TotalStudents - 1];	//新增数据的地址
	saveMeg(p);


}
void SetPos(int x, int y){
	COORD point = { x, y };//要设置光标的位置
	HANDLE HOutput = GetStdHandle(STD_OUTPUT_HANDLE);//
	SetConsoleCursorPosition(HOutput, point);
}
void StartShow(){

	int i, j;
	for (i = 0; i < 57; i++){
		for (j = 0; j < 14; j++){
			SetPos(4 + i, 4 + j);
			if ((i >= 1 && i <= 55) && (j >= 1 && j <= 12))
				printf(" ");
			else
				printf("*");
		}
	}
	SetPos(4 + 11, 18 - 3);
	printf("0) 退出软件");
	SetPos(4 + 11, 18 - 4);
	printf("5) 显示所有学生信息以及统计信息");
	SetPos(4 + 11, 18 - 5);
	printf("4) 查询学生信息");
	SetPos(4 + 11, 18 - 6);
	printf("3) 修改学生信息(根据学号)");
	SetPos(4 + 11, 18 - 7);
	printf("2) 删除学生信息(根据学号)");
	SetPos(4 + 11, 18 - 8);
	printf("1) 添加学生信息");
	SetPos(4 + 9, 4);
	printf("欢迎使用学生信息系统(当前共有%d名学生)", TotalStudents);

	for (i = 0; i < 32; i++){
		for (j = 0; j < 3; j++){
			SetPos(4 + 11 + i, 4 + 2 + j);
			if (j != 1)
				printf("-");
			else{
				SetPos(24, 7);
				printf("powered by wind");
			}
		}
	}
}

void ShowAll(){//显示所有学生信息及统计
	system("cls");
	StartShow();
	table(TotalStudents);
	int i;
	for (i = 0; i < TotalStudents; i++){
		SetPos(7, 22 + i); printf("%d", students[i].id);
		SetPos(15 - 1, 22 + i); printf("%s", students[i].name);
		SetPos(24, 22 + i); printf("%d", students[i].age);
		SetPos(31, 22 + i); printf("%s", students[i].sex);
		SetPos(40, 22 + i); printf("%.1lf", students[i].grade[0]);
		SetPos(47, 22 + i); printf("%.1lf", students[i].grade[1]);
		SetPos(55, 22 + i); printf("%.1lf", students[i].grade[2]);
		SetPos(63, 22 + i); printf("%.1lf", students[i].grade[3]);
	}
	SetPos(7, 22 + i + 1); system("pause");
}
void table(int num){
	//SetPos(5, 20);
	for (int i = 0; i < 65; i++){
		for (int j = 0; j < 3; j++){
			SetPos(5 + i, 19 + j);
			if (j != 1)
				printf("-");
			else{
				for (int k = 0; k < 65; k += 8){
					SetPos(5 + k, 19 + j);
					printf("|");
				}
			}
		}
	}

	SetPos(7, 20); printf("学号");
	SetPos(15, 20); printf("姓名");
	SetPos(24, 20); printf("年龄");
	SetPos(31, 20); printf("性别");
	SetPos(40, 20); printf("语文");
	SetPos(47, 20); printf("数学");
	SetPos(55, 20); printf("英语");
	SetPos(63, 20); printf("总分");

	for (int i = 0; i < 65; i++){
		for (int j = 0; j < num + 2; j++){//+2的意义:边框要大于要显示的数据条数
			SetPos(5 + i, 21 + j);
			if (j == 0 || j == num + 1)
				printf("-");
			else{
				for (int k = 0; k < 65; k += 8){
					SetPos(5 + k, 21 + j);
					printf("|");
				}
			}

		}
	}
}

int FindStu(){
	int num, i;
	system("cls");
	StartShow();
	SetPos(5, 18); printf("要查找的学号:");
	SetPos(21, 18); scanf_s("%d", &num);
	for (i = 0; i < TotalStudents; i++){
		if (students[i].id == num){
			table(1);
			SetPos(7, 22); printf("%d", students[i].id);
			SetPos(15 - 1, 22); printf("%s", students[i].name);
			SetPos(24, 22); printf("%d", students[i].age);
			SetPos(31, 22); printf("%s", students[i].sex);
			SetPos(40, 22); printf("%.1lf", students[i].grade[0]);
			SetPos(47, 22); printf("%.1lf", students[i].grade[1]);
			SetPos(55, 22); printf("%.1lf", students[i].grade[2]);
			SetPos(63, 22); printf("%.1lf", students[i].grade[3]);
			break;//不能忘记break
		}
	}
	return i;//返回即该学生在学生总数totalstudents中的下标
}
void DelStu(){
	char ch;
	int n, t;
	
	n = FindStu();
	//printf("得出n = %d", n);检查点
	t = students[n].id;	//学号
	SetPos(5, 25);
	printf("是否确定要删除:(Y/N)");
	while (1){
		if ((ch = getchar()) == 'Y'){
			for (int i = n; i < TotalStudents; i++){

				if (i < TotalStudents - 1){
					students[i].age = students[i + 1].age;
					students[i].grade[0] = students[i + 1].grade[0];
					students[i].grade[1] = students[i + 1].grade[1];
					students[i].grade[2] = students[i + 1].grade[2];
					students[i].grade[3] = students[i + 1].grade[3];
					students[i].id = students[i + 1].id;
					for (int j = 0; j < 10; j++)
						students[i].name[j] = students[i + 1].name[j];
					for (int j = 0; j < 4; j++)
						students[i].sex[j] = students[i + 1].sex[j];
				}
				else{
					students[i].age = 0;
					students[i].grade[0] = 0;
					students[i].grade[1] = 0;
					students[i].grade[2] = 0;
					students[i].grade[3] = 0;
					students[i].id = 0;
					for (int j = 0; j < 10; j++)
						students[i].name[j] = ' ';
					for (int j = 0; j < 4; j++)
						students[i].sex[j] = ' ';
				}
			}

			if (students[n].id != t){
				SetPos(5, 27);
				printf("删除成功\n");
				TotalStudents--;
				if (TotalStudents == 0){
					remove("mydata.txt");
				}
				else{
					Read_xuehao(t);
					ReadFileMeg();
				}
			}
			else{
				SetPos(5, 27);
				printf("删除失败\n");
			}
			system("pause");
			break;
		}
		else if (ch == 'n' || ch == 'N'){

			break;
		}
		/*else{
		SetPos(5, 27);
		printf("输入错误,请重新输入'Y' or 'N',不区分大小写");
		}*/
	}
}
void ChangeMeg(){//按学号修改学生信息
	int n;
	int t;
	int xuehao;
	n = FindStu();
	xuehao = students[n].id;
	//SetPos(7 + t * 8, 21); printf("1.姓名;2.年龄;3.性别;4.语文;5.数学;6.英语");
	SetPos(3, 24); printf("修改学号:<%d>学生的信息,选择(0-6):1.姓名;2.年龄;3.性别;4.语文;5.数学;6.英语;0-退出", students[n].id);

	t = 1;
	while (t){
		SetPos(7, 25); scanf_s("%d", &t); fflush(stdin);
		switch (t){
		case 1:
			SetPos(15 - 1, 22); scanf_s("%s", students[n].name, 10); fflush(stdin);
			break;
		case 2:
			SetPos(24, 22); scanf_s("%d", &students[n].age); fflush(stdin);
			break;
		case 3:
			SetPos(31, 22); scanf_s("%s", students[n].sex, 4); fflush(stdin);
			break;
		case 4:
			SetPos(40, 22); scanf_s("%lf", &students[n].grade[0]); fflush(stdin);
			break;
		case 5:
			SetPos(47, 22); scanf_s("%lf", &students[n].grade[1]); fflush(stdin);
			break;
		case 6:
			SetPos(55, 22); scanf_s("%lf", &students[n].grade[2]); fflush(stdin);
			break;
		default:
			break;
		}
		students[n].grade[3] = students[n].grade[0] + students[n].grade[1] + students[n].grade[2];
	}

	Read_to_change(xuehao, students, n);
	ReadFileMeg();
}
int int_to_str(int n, char str[]){
	int i;
	char temp;
	i = 0;
	while (n != 0){
		str[i] = (n % 10) + '0';
		n /= 10;
		i++;

	}
	for (int j = 0; j < i / 2; j++){
		temp = str[j];
		str[j] = str[i - 1 - j];
		str[i - 1 - j] = temp;
	}

	str[i] = '\0';
	i++;
	return i;
}
int str_to_int(int totalstu, char str[][8][20], Student students[]){//更新读取到的文件信息到students[],返回实际有效记录条数
	int i, j, t = 0;		//i,j:循环变量;
	for (i = 0; i < totalstu; i++){//遍历有效信息数组str[][][]
		for (j = 0; j < 8; j++){	//遍历单条记录的字段
			if (j == 1 || j == 3){	//注意strncpy_s(*dst, sizeof(dst), *src, sizeof(dst)-1)函数的用法
				strncpy_s((students + i)->name, sizeof((students + i)->name), str[i][1], sizeof((students + i)->name)-1);
				strncpy_s((students + i)->sex, sizeof((students + i)->sex), str[i][3], sizeof((students + i)->sex) - 1);				
			}
			else{	//	应用转换函数atoi()	atof()
				(students + i)->id = atoi(str[i][0]);
				(students + i)->age = atoi(str[i][2]);
				(students + i)->grade[0] = atof(str[i][4]);
				(students + i)->grade[1] = atof(str[i][5]);
				(students + i)->grade[2] = atof(str[i][6]);
				(students + i)->grade[3] = atof(str[i][7]);
			}
		}
		t++;
	}
	//for (i = 0; i < totalstu; i++){
	//	if (str[i][0][0] != ' ' || str[i][0][0] != ' '){
	//		if (str[i][0][0] != ' '){//记录有效的数据,若学号第一个字符不为空格,则为有效
	//			for (j = 0; j < 8; j++){
	//				if (j != 1 || j != 3){
	//					students[t].id = atoi(str[i][0]);
	//					students[t].age = atoi(str[i][2]);
	//					students[t].grade[0] = atof(str[i][4]);
	//					students[t].grade[1] = atof(str[i][5]);
	//					students[t].grade[2] = atof(str[i][6]);
	//					students[t].grade[3] = atof(str[i][7]);
	//				}
	//				for (k = 0; k < (int)strlen(str[i][j]); k++){//原数据为文字的直接存储到students[]中对应的字段
	//					if (j == 1 || j == 3){//tt[][][]数组中只有tt[][1][]和tt[][3][]字段为文字
	//						students[t].name[k] = str[i][1][k];
	//						students[t].sex[k] = str[i][3][k];
	//					}
	//				}
	//			}
	//			t++;
	//		}
	//	}
	//}
	return t;//返回有效的记录条数,是否省掉该返回值?
}
void saveMeg(Student *students){//从students[]中映射并保存新增的学生信息到文件
	FILE *fp = NULL;

	char tempch[8 + 1][20];

	fopen_s(&fp, "mydata.txt", "a+t");

	if (fp == NULL){
		printf("fail to open file\n");
	}

	int_to_str(students->id, tempch[0]);
	int_to_str(students->age, tempch[2]);
	int_to_str((int)students->grade[0], tempch[4]);//语文
	int_to_str((int)students->grade[1], tempch[5]);//数学
	int_to_str((int)students->grade[2], tempch[6]);//英语
	int_to_str((int)students->grade[3], tempch[7]);//总分数

	//注意strcpy_s()函数的局限性:src字符串被复制的数据不能大于dst字符串的空间大小,复制时会自动在末尾添加‘\0’,需要占用一个字符空间
	strcpy_s(tempch[1], sizeof(students->name), students->name);
	strcpy_s(tempch[3], sizeof(students->sex), students->sex);

	for (int i = 0; i < 8; i++){
		fputs("\t", fp);
		fputs(tempch[i], fp);
	}
	fputs("\n", fp);

	fclose(fp);
	recdnum++;	//新增数据到文件的同时也更新文件所有记录总条数(含无效记录)
}
void ReadFileMeg(){
	FILE *fp = NULL;

	fopen_s(&fp, "mydata.txt", "r+");
	if (fp == NULL){//若不存在则新建文件
		fopen_s(&fp, "mydata.txt", "a+");
	}

	char temp[50] = {0};//用于临时存储从文件中读取的每条记录
	char tt[50][8][20] = { 0 };//用于按字段解析temp中每条记录信息,并存储起来映射到students[]数组
	int i = 0;//文件信息行数的循环变量
	int j;//j用于循环遍历每次读取的行的单个字符
	int num = 0, k = -1, z = 0;//tt[num][k][z];
	//1、按行读取文件信息,
	//2、将每条信息按字段规则解析并保存,同时记录有效记录数量
	//3、将解析后的结果映射到students数组
	while ((fgets(temp, 50, fp)) != NULL){
		//有效记录第一个字符均为'\t',被删除的记录n-1个字符均为空格符' ',它们结尾均有一个换行符'\n'
		//先判断读取到的行的第一个字符,来确定是否是有效记录,再做处理
		if (temp[0] == '\t'){//判断第一个字符,有效记录
			j = 0;
			while (temp[j] != '\n'){
				if (temp[j] != '\t'){//过滤‘\t’字符,按字段存储解析结果
					tt[num][k][z] = temp[j];
					z++;//tt字段移动到下一个字符
					j++;//读取的记录移动到下一个字符
				}
				else{
					j++;//遇到'\t',读取的记录移动到下一个字符
					k++;//tt[][k][],移到下一个字段继续存储
					z = 0;//恢复到下一字段开始位置
				}
			}
			//一行记录读取完毕
			i++;//转到文件下一行
			num++;//准备存储下一行的解析结果
			k = -1;//恢复到下一个记录的第一个字段位置
			z = 0;//恢复到字段的第一个字符位置
		}
		else{//无效记录
			i++;//转下一行
			continue;//结束本条无效记录的遍历,开始下一条记录
		}
	}

	//整个文件读取完毕,开始将tt[][][]保存的信息映射到students[]
	fclose(fp);
	TotalStudents = num;//统计学生总数
	str_to_int(TotalStudents, tt, students);

}
void Read_xuehao(int xuehao){
	FILE *fp = NULL;

	fopen_s(&fp, "mydata.txt", "r+");
	
	char temp[50] = { 0 };//用于临时存储从文件中读取的每条记录
	char tt[50][8][20] = { 0 };//用于按字段解析temp中每条记录信息,并存储起来映射到students[]数组
	int i = 1;//文件信息行数的循环变量
	int j;//j用于循环遍历每次读取的行的单个字符
	int num = 0, k = -1, z = 0;//tt[num][k][z];
	int pianyi = 0;//表示偏移到要删除文件的末尾字符(含'\n')
	int len = 0;//要找寻的记录长度
	//1、按行读取文件信息,
	//2、将每条信息按字段规则解析并保存,同时记录有效记录数量
	//3、每解析一条记录,就比对一次,同时记录文件中已经读取了的偏移量(含无效记录)
	while ((fgets(temp, 50, fp)) != NULL){
		//有效记录第一个字符均为'\t',被删除的记录n-1个字符均为空格符' ',它们结尾均有一个换行符'\n'
		//先判断读取到的行的第一个字符,来确定是否是有效记录,再做处理
		if (temp[0] == '\t'){//判断第一个字符,有效记录
			j = 0;
			while (temp[j] != '\n'){
				if (temp[j] != '\t'){//过滤‘\t’字符,按字段存储解析结果
					tt[num][k][z] = temp[j];
					z++;//tt字段移动到下一个字符
					j++;//读取的记录移动到下一个字符
				}
				else{
					j++;//遇到'\t',读取的记录移动到下一个字符
					k++;//tt[][k][],移到下一个字段继续存储
					z = 0;//恢复到下一字段开始位置
				}
			}
			
			//一行记录读取完毕立即开始比对
			len = strlen(temp)+1;//'\0'
			pianyi += len;//将该条记录长度添加到偏移量(含末尾'\n'),
			if (xuehao == atoi(tt[num][0])){//找到				
				break;
			}
			else{//没找到,就开始下一条记录
				//i++;//转到文件下一行
				num++;//准备存储下一行的解析结果
				k = -1;//恢复到下一个记录的第一个字段位置
				z = 0;//恢复到字段的第一个字符位置
			}
		}
		else{//无效记录,也要统计长度加到偏移量总数中来
			while (temp[i] != '\0'){
				i++;
			}
			pianyi += i;//将无效记录的长度加入偏移量中
			i = 0;;//i清零,转下一行
			continue;//结束本条无效记录的遍历,开始下一条记录
		}
	}
	//printf("pianyi = %d\tlen = %d\tstartpoint = %d\n", pianyi, len, pianyi-len);
	Del_File_rec(pianyi, len, fp);

	fclose(fp);

}
void Del_File_rec(int pianyi, int len, FILE *fp){
	int starpoint = 0;
	starpoint = pianyi - len;
	fseek(fp, starpoint, SEEK_SET);
	if (starpoint == 0){//文件中第一条记录的特殊性
		//len += 2;
		while (len > 1){
			fputs(" ", fp);
			len--;
		}
	}
	else{
		while (len > 2){//记录的最后两个个字符'\n''\0'不删除
			fputs(" ", fp);
			len--;
		}
	}
	

}
void changetosave(Student *students, FILE *fp){

	char tempch[8 + 1][20];

	int_to_str(students->id, tempch[0]);
	int_to_str(students->age, tempch[2]);
	int_to_str((int)students->grade[0], tempch[4]);//语文
	int_to_str((int)students->grade[1], tempch[5]);//数学
	int_to_str((int)students->grade[2], tempch[6]);//英语
	int_to_str((int)students->grade[3], tempch[7]);//总分数

	//注意strcpy_s()函数的局限性:src字符串被复制的数据不能大于dst字符串的空间大小,复制时会自动在末尾添加‘\0’,需要占用一个字符空间
	strcpy_s(tempch[1], sizeof(students->name), students->name);
	strcpy_s(tempch[3], sizeof(students->sex), students->sex);

	for (int i = 0; i < 8; i++){
		fputs("\t", fp);
		fputs(tempch[i], fp);
	}
	fputs("\n", fp);
}
void Read_to_change(int xuehao, Student *students, int n){
	FILE *fp = NULL;

	fopen_s(&fp, "mydata.txt", "r+");

	char temp[50] = { 0 };//用于临时存储从文件中读取的每条记录
	char tt[50][8][20] = { 0 };//用于按字段解析temp中每条记录信息,并存储起来映射到students[]数组
	int i = 1;//文件信息行数的循环变量
	int j;//j用于循环遍历每次读取的行的单个字符
	int num = 0, k = -1, z = 0;//tt[num][k][z];
	int pianyi = 0;//表示偏移到要删除文件的末尾字符(含'\n')
	int len = 0;//要找寻的记录长度
	//1、按行读取文件信息,
	//2、将每条信息按字段规则解析并保存,同时记录有效记录数量
	//3、每解析一条记录,就比对一次,同时记录文件中已经读取了的偏移量(含无效记录)
	while ((fgets(temp, 50, fp)) != NULL){
		//有效记录第一个字符均为'\t',被删除的记录n-1个字符均为空格符' ',它们结尾均有一个换行符'\n'
		//先判断读取到的行的第一个字符,来确定是否是有效记录,再做处理
		if (temp[0] == '\t'){//判断第一个字符,有效记录
			j = 0;
			while (temp[j] != '\n'){
				if (temp[j] != '\t'){//过滤‘\t’字符,按字段存储解析结果
					tt[num][k][z] = temp[j];
					z++;//tt字段移动到下一个字符
					j++;//读取的记录移动到下一个字符
				}
				else{
					j++;//遇到'\t',读取的记录移动到下一个字符
					k++;//tt[][k][],移到下一个字段继续存储
					z = 0;//恢复到下一字段开始位置
				}
			}

			//一行记录读取完毕立即开始比对
			len = strlen(temp) + 1;//'\0'
			pianyi += len;//将该条记录长度添加到偏移量(含末尾'\n'),
			if (xuehao == atoi(tt[num][0])){//找到				
				break;
			}
			else{//没找到,就开始下一条记录
				//i++;//转到文件下一行
				num++;//准备存储下一行的解析结果
				k = -1;//恢复到下一个记录的第一个字段位置
				z = 0;//恢复到字段的第一个字符位置
			}
		}
		else{//无效记录,也要统计长度加到偏移量总数中来
			while (temp[i] != '\0'){
				i++;
			}
			pianyi += i;//将无效记录的长度加入偏移量中
			i = 0;;//i清零,转下一行
			continue;//结束本条无效记录的遍历,开始下一条记录
		}
	}
	//printf("pianyi = %d\tlen = %d\tstartpoint = %d\n", pianyi, len, pianyi-len);
	Del_File_rec(pianyi, len, fp);
	fseek(fp, 0, SEEK_END);
	changetosave(&students[n], fp);
	fclose(fp);

}

void Initial(){

	int xuanze, T;

	StartShow();
	SetPos(5, 18);
	printf("请选择相应功能的序号(0-5):\t");
	T = 1;
	while (T){
		scanf_s("%d", &xuanze); fflush(stdin);
		switch (xuanze){
		default:
			;
		case 0:

			SetPos(5, 18); printf("是否确定退出程序(大写):Y / N");
			SetPos(5, 19);
			char ch;
			/*ch = scanf_s("%c", &ch); getchar();*/
			if ((ch = getchar()) == 'Y'){//输入小写字母的问题尚未解决
				T = 0;
			}
			else if (ch == 'n' || ch == 'N'){
				system("cls");
				StartShow();
				SetPos(5, 18);
				printf("请选择相应功能的序号(0-5):\t");
			}
			break;
		case 1://添加
			AddStu();
			SetPos(5, 28);
			system("cls");
			StartShow();
			SetPos(5, 18);
			printf("请选择相应功能的序号(0-5):\t");
			break;
		case 2://删除
			DelStu();
			SetPos(5, 28);
			//system("pause");
			system("cls");
			StartShow();
			SetPos(5, 18);
			printf("请选择相应功能的序号(0-5):\t");
			break;
		case 3://修改
			ChangeMeg();
			SetPos(5, 28);
			system("pause");
			system("cls");
			StartShow();
			SetPos(5, 18);
			printf("请选择相应功能的序号(0-5):\t");
			break;
		case 4://查询
			FindStu();
			SetPos(5, 28);
			system("pause");
			system("cls");
			StartShow();
			SetPos(5, 18);
			printf("请选择相应功能的序号(0-5):\t");
			break;
		case 5:
			ShowAll();
			/*SetPos(5, 28);
			system("pause");*/
			system("cls");
			StartShow();
			SetPos(5, 18);
			printf("请选择相应功能的序号(0-5):\t");
			break;
		}
	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值