c语言如何从文件中读取信息到链表——文件操作

写这篇博客原因:

c程序课设 忙的头昏脑涨,看了大量的博客。但是发现,文件操作这方面很少有简单易懂实用的博客。我作为大一新生,把自己学到的一点点文件操作功能分享一下。希望可以加快学者们的步伐。
源代码在最下面!
已更新代码 新加说明书界面 修改信息功能及界面超帅
再次更新代码 新加了智能化功能
**1.读取文件信息到链表。 省去了手动输入的麻烦

老师力推这个功能!!

2.删除读入的全部信息。**
与基本功能配套使用 很完美

喔对了。系统可以使用特殊符号 记得自己尝试一下
《c语言如何从文件中读取信息到链表——文件操作》

《c语言如何从文件中读取信息到链表——文件操作》

还没学如何快速到达自己感兴趣的模块 不好意思。。。。
1.数据储存到文件
2.如何按格式读取文件想要的信息,常用于密码登录。

进入正题:

先看效果 是不是你们想要的。《c语言如何从文件中读取信息到链表——文件操作》
这是写出后的两个文件对比;
左边是录入原数据,右边是排名计算后写入的数据。

上代码(可以先看下代码下方的分部解析)

1.原始数据储存 功能函数

void Save_massage1(struct stu*p_Head) { 
		struct stu* p = p_Head;
		char s[100] = {  "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 \n" };
		char s2[100] = {  "-----------------------------------------------------------------------------------\n" };
		//打开文件
		//定义一个文件指针p_file 
		FILE* p_File;//这里是文件结构体声明 这里不展开。没有它不行
		p_File = fopen("playerOriginal.dat.txt", "w");

		if (p_File == NULL) { 
			printf("打开文件失败\n");
			return 0;           //exit (0);
		}
		else
			//写入数据
		{ 
			fprintf(p_File, "%s", s);
			fprintf(p_File, "%s", s2);
			
			while (p!= NULL)
			{ 
				
				int i = 0;
 				fprintf(p_File, "%s\t", p->name);
				fprintf(p_File, "%d\t", p->rank);
				for (i = 0; i < 10; i++)
				{ 
					fprintf(p_File, "%6.2f", p->score[i]);
				}
			
				fprintf(p_File, "\n");
				p = p->p_next;
			}
		}
		printf("本地保存成功\n");

		//关闭文件
		fclose(p_File);
	}

首先看这个格式:如何实现?
《c语言如何从文件中读取信息到链表——文件操作》

先将你的格式写入字符串 ,用fprintf库函数先将你的格式所在的字符数组写入文件,然后在写入链表内容数据。
(不用fwrite是因为这个是二进制写入 写int 数据会乱码 所以没有深入了解)
《c语言如何从文件中读取信息到链表——文件操作》

2.排名后数据储存 功能函数

void Save_massage2(struct stu* p_Head) { 
		//打开文件
		//定义一个文件指针p_file 
		FILE* p_File; //这里是文件结构体声明 这里不展开。没有它不行
		p_File = fopen("playerGrade.dat.txt", "w");

		if (p_File == NULL) { 
			printf("打开文件失败\n");
			return 0;           //exit (0);
		}
		else
			printf("本地保存成功\n");
		struct stu* p = p_Head;
		char s[100] = {  "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average\n" };
		char s2[100] = {  "---------------------------------------------------------------------------------------------\n" };
		//写入数据
		fprintf(p_File, "%s", s); 
		fprintf(p_File, "%s", s2);
		while (p != NULL)
		{ 
			int i = 0;
			fprintf(p_File, "%s\t", p->name);
			fprintf(p_File, "%d\t", p->rank);
			for (i = 0; i < 10; i++)
			{ 
				fprintf(p_File, "%6.2f", p->score[i]);
			}
			fprintf(p_File, "%6.2f\n", p->aver);
			
			p = p->p_next;
		}

		//关闭文件
		fclose(p_File);
	}

这里的实现跟上面那个差不多
这个文件名要自己输入你的txt文件名**(txt文件与你的c语言代码源文件在一起哦!一个人多孤单!)**
《c语言如何从文件中读取信息到链表——文件操作》
文件比较乱哈哈
《c语言如何从文件中读取信息到链表——文件操作》

3.最后一个文件操作功能压轴出场:
文件写入后的读取,与密码登录系统有关。

如何正确读取你想要的数据呢。
看代码!

/* struct stu { int rank; char name[20]; float score[10]; float aver; struct stu* p_next; }; struct Stu { int rank; char name[20]; float score[10]; float aver; };*/
	//这里用的是第二个 读取信息。
	//第一个是链表节点

void Read_file(char name[])
	{ 
	
		
		int i;
		struct Stu p_temp = {  0," ",0,0 };   //这里用的是vs2019 如果代码不在一个文件内 需要进行结构体定义;
		FILE* fp;
		char filename[30] = {  "playerGrade.dat.txt" };//z这里是要读取的文件名
		
		if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败
		{ 
			printf("can not open!\npress any key to continue\n");
			getchar();
			exit(0);
		}
		else
		{ 
			
			int j;
			//对文件读写操作 行 列。 for 循环 行读取 便读取边赋值结构体变量。
			fseek(fp,173, 0);//跳过开头
			for (i = 0; i<N; i++)
			{ 
//这里比较笨拙 读者看看有没有方法简化 这里用fscanf 库函数 注意 %f与f%之间是空格哦 要注意这个问题 写入文件的时候就是隔个空格 写出格式要相同
				fscanf(fp, "%s %d %f %f %f %f %f %f %f %f %f %f %f\n", &p_temp.name, &p_temp.rank, &p_temp.score[0], &p_temp.score[1], &p_temp.score[2], &p_temp.score[3], &p_temp.score[4], &p_temp.score[5], &p_temp.score[6], &p_temp.score[7], &p_temp.score[8], &p_temp.score[9], &p_temp.aver);
 


				//是否找到
				//这里采用名字登录,读者可以升级为学号登录。
				if (strcmp(p_temp.name, name) == 0)
				{ 
					Menu_player();//这里是我自定义的界面函数 可忽略
					system("pause");//忽略
					

//这个是界面设置 前面一半在主函数 读者自己设计界面美化
//下面的printf 内的** 星号 空格都是为了界面美化搞得 可以不要
					printf("** 姓名%s\t", p_temp.name);
					printf("排名%d\t", p_temp.rank);
					//十个评委的分数可不要
					/*for (j = 0; j < 10; j++) { printf("%6.2f ", p_temp.score[j]); }*/
					printf("最终成绩:%6.2f **\n", p_temp.aver);
					printf("*************************************************\n");
					printf("************--欢迎下年再来--*********************\n");
					break;

				}
			}
				//文件查找 相同姓名 然后输出那一行内容
			if (strcmp(p_temp.name, name) != 0)
				printf("输入信息错误,或者未录入。");
			system("pause");
			system("cls");
			fclose(fp);
		}

问题来了:
1.文件内容开头是我们的格式 并不需要读取,那么怎么跳过?
《c语言如何从文件中读取信息到链表——文件操作》
这里利用fseek库函数
fseek(fp,173, 0);//跳过开头格式
fseek(文件指针,跳过的字节数,从哪里开始跳)
文件指针 经过上面两个信息储存大家应该了解了,
那么字节数怎么把控?一个一个数?其中’+’’-‘代表往前往后跳。
我们用的是+
往哪里跳,0 开头,1当前所在位置 这个目前还没用过,2从尾开始跳
我们用的是0 开头

下面就看怎么获得格式数据的字节数了 ,如何刚刚好跳过没用信息?
看操作

《c语言如何从文件中读取信息到链表——文件操作》
《c语言如何从文件中读取信息到链表——文件操作》
都秒懂是吧???
不过要注意
这里我读取的是我的第二个文件
两个文件的格式不一样哦《c语言如何从文件中读取信息到链表——文件操作》
《c语言如何从文件中读取信息到链表——文件操作》
多一个average
2.如何正确读取文件数据到变量;
我这里写入的时候就是用的链表数据写入的
所以我定义了一个结构体 类型 不含 next指针
《c语言如何从文件中读取信息到链表——文件操作》
用第二种;

看代码:

呃,,,,自己往上面翻。

下面将我的整个代码给出来吧。
我是用vs2019 写的 忽略scanf警告
如何忽略?
看图 两种方法
《c语言如何从文件中读取信息到链表——文件操作》
右击源文件 点属性

《c语言如何从文件中读取信息到链表——文件操作》
《c语言如何从文件中读取信息到链表——文件操作》

在预处理器定义内输入 _CRT_SECURE_NO_WARNINGS

每建立一个新文件都需要这个操作

第二种方法;
在代码前头加
#define _CRT_SECURE_NO_WARNING

例如:
《c语言如何从文件中读取信息到链表——文件操作》

《c语言如何从文件中读取信息到链表——文件操作》

如果有不足的地方或者可以优化的地方 还望指出 每个代码人 都渴望提升啊。

评分管理系统要求如图:
《c语言如何从文件中读取信息到链表——文件操作》
《c语言如何从文件中读取信息到链表——文件操作》
《c语言如何从文件中读取信息到链表——文件操作》

#include<stdio.h>
#include<string.h>
#include<process.h>
int i_count=0;
int menu1=1, menu2=1;//菜单选项
#define N 10 //最大节点数 可修改
     
//说明书界面
    void Menu_help()
{ 
	printf("*****************比赛评分系统灿哥版520.v*******************\n");
	printf("** **\n");
	printf("**_____________________--欢迎使用--_____________________ **\n");
	printf("** **\n");
	printf("** **\n");
	printf("***************《详细说明书.爱心6.0tv版》******************\n");
	printf("**-------------------------------------------------------**\n");
	printf("** **\n");
	printf("**一、姓名确定身份!决定你的权限 **\n");
	printf("** **\n");
	printf("**二、按照功能菜单进行键入对应数字! **\n");
	printf("** **\n");
	printf("**三、选手只能查取自己对应的最终成绩! **\n");
	printf("** **\n");
	printf("**四、管理员切记按正常顺序操作,记得保存录入的信息到文件!**\n");
	printf("** **\n");
	printf("**--------------------【任意键返回】---------------------**\n");
	printf("***********************************************************\n");
}
//修改信息时的界面
	void Menu_moidfy()
	{ 
	
		printf("*****--修改系统--*****\n");
		printf("**------------------**\n");
		printf("** 1.修改序号 **\n");
		printf("** 2.修改姓名 **\n");
		printf("** 3.修改成绩 **\n");
		printf("** 4.退出菜单 **\n");
		printf("**------------------**\n");
		printf("***************************\n");
		printf("*|-----------------------**\n");
		printf("*| **\n");
	}
//管理员界面
    void Menu_gaver()
{ 
	printf("\n****************╭ ||管理版||╮********************\n");
	printf("*\t 欢迎使用比赛评分系统 \t\t*\n");
	printf("*\t\t ╭ (`ε`)╮\t\t\t*\n");

	printf("*************************************************\n");
	printf("*-----------------------------------------------*\n");
	printf("*\t\t 1.智能化功能\t\t\t*\n");
	printf("*\t\t 2.手动功能\t\t\t*\n");
	printf("*\t\t 0.退出系统\t\t\t*\n");
	printf("*************************************************\n");
	printf("||→_→ 请输入功能菜单序号:");
}
//选手界面
	void Menu_player()
	{ 
		printf("\n*******************选手版************************\n");
		printf("*\t\t欢迎使用\t\t\t*\n");
		printf("*\t\t祝您好运!\t\t\t*\n");
		printf("*************************************************\n");
		printf("*************************************************\n");
		printf("*************************************************\n");
		printf("*\t\t一键查取成绩\t\t\t*\n");
		printf("*************************************************\n");
		printf("*************************************************\n"); 
	}
	void Menu_intellent()
	{ 
		printf("\n****************╭ ||管理版||╮********************\n");
		printf("*\t 欢迎使用比赛评分系统 \t\t*\n");
		printf("*\t\t ⊙﹏⊙\t\t\t*\n");

		printf("*************************************************\n");
		printf("******************智能化功能*********************\n");
		printf("*-----------------------------------------------*\n");
		printf("*\t\t1.智能读取文件信息\t\t*\n");//后期加入 
		printf("*\t\t2.批量删除选手信息\t\t*\n");//后期加入 
		printf("*\t\t0.返回上一级\t\t\t*\n");
		printf("*************************************************\n");
		printf("||-->请输入功能菜单序号:");
	}
		
	void Menu_hand()
	{ 
		printf("\n****************╭ ||管理版||╮********************\n");
		printf("*\t 欢迎使用比赛评分系统 \t\t*\n");
		printf("*\t\t T^T\t\t\t*\n");

		printf("*************************************************\n");
		//printf("* *\n");
		printf("*******************人工功能**********************\n");
		printf("*-----------------------------------------------*\n");
		printf("*\t\t1.录入选手信息\t\t\t*\n");
		printf("*\t\t2.删除退赛选手信息\t\t*\n");
		printf("*\t\t3.插入新选手信息\t\t*\n");
		printf("*\t\t4.修改信息\t\t\t*\n");  //后期新加入的
		printf("*\t\t5.保存数据\t\t\t*\n");
		printf("*\t\t6.自动排名保存\t\t\t*\n");
		printf("*\t\t7.输出全部信息\t\t\t*\n");
		printf("*\t\t8.输入姓名查信息\t\t*\n");
		printf("*\t\t9.详细说明书\t\t\t*\n");
		printf("*\t\t0.退出系统\t\t\t*\n");
		printf("*************************************************\n");
		printf("||-->请输入功能菜单序号:");
	}


	struct stu { 
	int rank;
	char name[20];
	float score[10];
	float aver;
	struct stu* p_next;
};
	struct Stu { 
		int rank;
		char name[20];
		float score[10];
		float aver;
	};
	struct stu* p_end = NULL;//全局变量 尾指针
	struct stu* p_Head = NULL;//头结点

	void creat(void){ 
		int i;//I表示输入的选手序号 后期排序用 排名
		/*struct stu* p_head = NULL;*/
		struct stu* p;
		p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存
		printf("输入的第几个选手:\n");
		scanf("%d",&p->rank );
		while (p->rank != i_count + 1)
		{ 

			printf("输入序号不对!\n");
			printf("请重新输入!\n");
			scanf("%d", &p->rank);
		}
		
		printf("输入选手姓名:\n");
		scanf("%s", &p->name);
		
		for (i = 0; i < 10; i++)
		{ 
			printf("\t第%d个成绩:", i+1);
			scanf("%f", &p->score[i]);
			
		}
		while (1)
		{    
			i_count++;
			if (i_count == 1)
			{ 
				p->p_next = p_Head;//此时head为null 使新节点下一个指向null
				p_Head = p; //头指针赋值
				p_end = p;
			}
			else { 
				p->p_next = NULL;  //与第一个节点相同 需要将新节点next 指向null
				p_end->p_next = p;//将新旧节点搭建关系
				p_end = p;//尾指针更新
			}
			p = (struct stu*)malloc(sizeof(struct stu));
			printf("输入的第几个选手:\n");
			printf("输入0结束\n");
			scanf("%d", &p->rank);     //输入0 结束
			if (0==p->rank)
				break;
			while (p->rank != i_count+1)
			{ 

					printf("输入序号不对!\n");
					printf("请重新输入!\n");
					scanf("%d", &p->rank);
			}
			printf("输入选手姓名:\n");
			scanf("%s", &p->name);
			for (i = 0; i < 10; i++)
			{ 
				printf("\t第%d个成绩:", i+1);
				scanf("%f", &p->score[i]);
			}

		}
		free(p);
		//return p_Head;
	}
	
	void Modify() //修改动态链表内信息 不能改已经排好序存到文件的信息
	{                                      //在程序未关闭前,可以改original 但绝对不改grade文件内的 实际安全问题
		struct stu* p = p_Head;
		char name[20];
		int num;
		int i;
		printf("请输入要要修改的学生的姓名:\n");
		scanf("%s", &name);
		printf("请输入要要修改的学生的序号:\n"); //序号不会错 或者很少用 这个当娱乐
		scanf("%d", &num);                     //修改的话只能修改重复型错误 不要往后修改
		getchar();
		for (i = 0; i < i_count; i++) { 
			if (strcmp(p->name, name) == 0 || p->rank == num)//判断要删除的人
			{ 
				
				while (1)
				{ 
					system("cls");
					Menu_moidfy();
					printf("*|请选择菜单编号:");
					char ch = getchar();
					switch (ch)
					{ 
					case '1':
						printf("*|请输入新的序号:");
						scanf("%d", &p->rank);
						printf("*|修改序号成功!\n");
						system("pause");
						getchar();
						system("cls");
						break;
					case '2':
						printf("*|请输入新的姓名:");
						scanf("%s", &p->name);
						printf("*|修改姓名成功!\n");
						system("pause");
						getchar();
						system("cls");
						break;
					case '3':
						printf("*|请输入新的成绩:\n");
						for (i = 0; i < 10; i++)
						{ 
							printf("*|\t第%d个成绩:", i+1); 
							scanf("%f", &p->score[i]);
						}
						printf("*|修改成绩成功!\n");
						system("pause");
						getchar();
						system("cls");

						break;

					case '4':
						printf("*|修改完毕!请及时保存到本地!\n");
						return;//与break 不同 试试exit
					default:
						printf("请在1-4之间选择\n");

					}
				}
				
			}
			
			else
			{ 
				p = p->p_next;
			}
		}
		if (p== NULL)
		{ 
			printf("未识别该选手!!!\n");
		}
	}
	
	//用遍历链表 search 解决了报告要求的输出三个内容 排名 分数
	struct stu* Search_name(struct stu* p_Head,char name[]) { 
		
		struct stu* p = p_Head;
		while (p!= NULL)
		{ 
			if (strcmp(name, p->name)==0)
			{ 
				break;
			}
			else
			{ 	
				p = p->p_next;
			}
		}
		return p;

	}
	void Sort_aver(struct stu* p_Head)
	{ 
		int i, j, I, J, T;
		float sum, temp;
		struct stu* p = p_Head;
		for (i = 0; i < i_count; i++)
		{ 
			//先进行一个排序 从2-9 操作 选择排序 求平均分
			for (I = 0; I < 10; I++)
			{ 
				T = I;
				temp = p->score[I];
				for (J = I + 1; J < 10; J++)
				{ 
					if (temp > p->score[J])
					{ 
						temp = p->score[J];//这里 temp 已经存了j 对应的最小值了
						T = J;
					}
				}
				if (T != I)
				{ 
					p->score[T] = p->score[I];
					p->score[I] = temp;
				}

			}
			for (j = 1, sum = 0; j < 9; j++)
			{ 
				sum += p->score[j];

			}
			p->aver = sum / 8;
			p = p->p_next;
		}
	}
	void Rank(struct stu* p_Head) { 
		float temp;
		int t,i,j;
		struct stu* p = p_Head;
		struct stu Temp;
		struct stu* p1 = NULL;//p1 p2 要交换的两个节点
		struct stu* p2 = NULL;
		p1 = p_Head;
		//选择排序思想排序 节点 对成员进行排名
		for (i = 1; i <= i_count; i++)
		{ 
			t = i;
			temp=p->aver;
			p = p->p_next;
			for (j = i + 1; j <=i_count; j++)
			{ 
				if (temp<p->aver)
				{ 
					t = j;
					p2 = p;//储存要交换的节点地址;
					temp = p->aver;
				}
				p = p->p_next;
			}

			if (t != i)
			{ 
				//p1->rank = ;
				//p2->rank = i;
			//排名交换
			p2->rank = i;
			p1->rank = t;

			//数据交换
			Temp=*p1;                      //交换节点
			memcpy(p1, p2, 68);
			memcpy(p2, &Temp, 68);
		
			}
			p1 = p1->p_next;
			p = p1;
		}
		 
	}
	struct stu* Delete(struct stu* p_Head, int index)	//pHead表示头结点,iIndex表示要删除的结点下标
	{ 
		int i;
		int temp2 = 1;//同下 专门解决连续删除两次头节点
		int temp = i_count;//专门解决 间断性删除两次尾节点造成的问题
		struct stu* p_temp;		 /*临时指针*/
		struct stu* p_pre;		/*表示要删除结点前的结点*/
		p_pre = p_temp = p_Head;				//得到头结点
		//删除头结点
		if (index == temp2)
		{ 
			p_temp = p_Head->p_next;
			p_Head = NULL;
			free(p_Head);				//释放掉要删除结点的内存空间
			i_count--;
			temp2++;
			return p_temp;

		}
		//删除尾结点
		else if (index ==temp)
		{ 
			for (i = 1; i < index; i++)		//for循环使得pTemp指向要删除的结点
			{ 
				//专门解决 间断性删除两次尾节点造成的问题
				p_pre = p_temp;
				p_pre->p_next = NULL;//找到要删除的节点
				free(p_temp);
				temp--;
				i_count--;
				return p_Head;
			}
		}
		//删除中间节点
		else
		{ 
			for (i = 1; i < index; i++)		//for循环使得pTemp指向要删除的结点
			{ 
				p_pre = p_temp;
				p_temp = p_temp->p_next;//找到要删除的节点
			}
			p_pre->p_next = p_temp->p_next;	//好理解 这里与其他操作不同 两边的操作类型相同 /*连接删除结点两边的结点*/
			free(p_temp);				//释放掉要删除结点的内存空间
			i_count--;					//减少链表 中的元素个数*/
			return p_Head;
		}
	}
	void Save_massage1(struct stu*p_Head) { 
		struct stu* p = p_Head;
		char s[100] = {  "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 \n" };
		char s2[100] = {  "-----------------------------------------------------------------------------------\n" };
		//打开文件
		FILE* p_File;
		p_File = fopen("playerOriginal.dat.txt", "w");

		if (p_File == NULL) { 
			printf("打开文件失败\n");
			return 0;           //exit (0);
		}
		else
			//写入数据
		{ 
			fprintf(p_File, "%s", s);
			fprintf(p_File, "%s", s2);
			
			while (p!= NULL)
			{ 
				
				int i = 0;
 				fprintf(p_File, "%s\t", p->name);
				fprintf(p_File, "%d\t", p->rank);
				for (i = 0; i < 10; i++)
				{ 
					fprintf(p_File, "%6.2f", p->score[i]);
				}
			
				fprintf(p_File, "\n");
				p = p->p_next;
			}
		}
		printf("本地保存成功\n");

		//关闭文件
		fclose(p_File);
	}
	void Save_massage2(struct stu* p_Head) { 
		//打开文件
		FILE* p_File;
		p_File = fopen("playerGrade.dat.txt", "w");

		if (p_File == NULL) { 
			printf("打开文件失败\n");
			return 0;           //exit (0);
		}
		else
			printf("本地保存成功\n");
		struct stu* p = p_Head;
		char s[100] = {  "NAME\tNO.\t sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average\n" };
		char s2[100] = {  "---------------------------------------------------------------------------------------------\n" };
		//写入数据
		fprintf(p_File, "%s", s);
		fprintf(p_File, "%s", s2);
		while (p != NULL)
		{ 
			int i = 0;
			fprintf(p_File, "%s\t", p->name);
			fprintf(p_File, "%d\t", p->rank);
			for (i = 0; i < 10; i++)
			{ 
				fprintf(p_File, "%6.2f", p->score[i]);
			}
			fprintf(p_File, "%6.2f\n", p->aver);
			
			p = p->p_next;
		}

		//关闭文件
		fclose(p_File);
	}


	void Print(struct stu* p_Head) // 前后都要输出
	{ 
		extern i_count;
		int i, j;
		struct stu* p = p_Head;
		printf("****************************************************************************************************\n");
		printf("************************************《灿哥最帅》****************************************************\n");
		printf(" **\n");

		printf("共查询到%d个选手信息: **\n", i_count);
		printf("name\tNO.\taverge\tscore1 score2 score3 score4 score5 score6 score7 score8 score9 score10 **\n");
		printf("--------------------------------------------------------------------------------------------- **\n");


		for (i = 0; i < i_count; i++)
		{ 
			printf("%s\t", p->name);
			printf("%d\t", p->rank);
			printf("%6.2f\t", p->aver);
			for (j = 0; j < 10; j++)
			{ 
				printf("%6.2f,", p->score[j]);
			}
			printf(" **\n");
			p = p->p_next;
		}
		printf(" **\n");
		printf("***********************************《534宿舍赞助》**************************************************\n");
		printf("****************************************************************************************************\n");

	}
	//用文件判定学生还是管理
	void Read_file(char name[])
	{ 
	
		//char s[] = { "NAME NO. sco1 sco2 sco3 sco4 sco5 sco6 sco7 sco8 sco9 sco10 average--------------------------------------------------------------------------------------------"};//后面用于读文件使用
		/*struct Stu { int rank; char name[20]; float score[10]; float aver;*/
		int i;
		struct Stu p_temp = {  0," ",0,0 };
		FILE* fp;
		char filename[30] = {  "playerGrade.dat.txt" };
		
		if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败
		{ 
			printf("can not open!\npress any key to continue\n");
			getchar();
			exit(0);
		}
		else
		{ 
			
			int j;
			//对文件读写操作 行 列。 for 循环 行读取 便读取边赋值结构体变量。
			fseek(fp,173, 0);//跳过开头
			for (i = 0; i<N; i++)
			{ 

				fscanf(fp, "%s %d %f %f %f %f %f %f %f %f %f %f %f\n", &p_temp.name, &p_temp.rank, &p_temp.score[0], &p_temp.score[1], &p_temp.score[2], &p_temp.score[3], &p_temp.score[4], &p_temp.score[5], &p_temp.score[6], &p_temp.score[7], &p_temp.score[8], &p_temp.score[9], &p_temp.aver);



				//是否找到
				if (strcmp(p_temp.name, name) == 0)
				{ 
					Menu_player();
					system("pause");
					


					printf("** 姓名%s\t", p_temp.name);
					printf("排名%d\t", p_temp.rank);
					//十个评委的分数可不要
					/*for (j = 0; j < 10; j++) { printf("%6.2f ", p_temp.score[j]); }*/
					printf("最终成绩:%6.2f **\n", p_temp.aver);
					printf("*************************************************\n");
					printf("************--欢迎下年再来--*********************\n");
					break;

				}
			}
				//文件查找 相同姓名 然后输出那一行内容
			if (strcmp(p_temp.name, name) != 0)
				printf("输入信息错误,或者未录入。");
			system("pause");
			system("cls");
			fclose(fp);
		}
	}
	void Refresh(struct stu* p_Head) { 

		while (i_count--)
		{ 
			struct stu* p = p_Head;
			p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存
			p_Head = p->p_next;
			free(p);
		}
		i_count = 0;

	}
	void Read_massage_file(int num)
	{ 

		struct stu* p;
		p = (struct stu*)malloc(sizeof(struct stu));//开辟结构体变量内存
		FILE* fp;
		char filename[30]; //= { "2.txt" };//可以键入 
		printf("请输入要读取的文件:");
		scanf("%s", &filename);
		getchar();
		if ((fp = fopen(filename, "r+")) == NULL)//判断文件是否打开失败
		{ 
			printf("打开失败!\n");
			getchar();
			system("pause");
			exit(0);
		}
		else
		{ 
			
			while (num--)
			{ 
				i_count++;
				if (i_count == 1)
				{ 
					p->p_next = NULL;//此时head为null 使新节点下一个指向null
					p_Head = p; //头指针赋值
					p_end = p;
				}
				else
				{ 
					p->p_next = NULL;  //与第一个节点相同 需要将新节点next 指向null
					p_end->p_next = p;//将新旧节点搭建关系
					p_end = p;//尾指针更新
				}
				fscanf(fp, "%s %d %f %f %f %f %f %f %f %f %f %f \n", &p->name, &p->rank, &p->score[0], &p->score[1], &p->score[2], &p->score[3], &p->score[4], &p->score[5], &p->score[6], &p->score[7], &p->score[8], &p->score[9]);
				p = (struct stu*)malloc(sizeof(struct stu));
			}
			free(p);


		}

		printf("读入成功!\n");
		fclose(fp);
	}

	int main()
	{ 
		struct stu* p5 = NULL;


		int n = 1;
		char Name[20] = {  "\0" };
		char manage[20] = {  "pipili" };
		printf("************比赛评分系统灿哥版520.v***************\n");
		printf("** **\n");
		printf("**________________--欢迎使用--__________________**\n");
		printf("** **\n");
		printf("** **\n");
		printf("** 请输入你的姓名:");

		scanf("%s", &Name);
		getchar();
		printf("** **\n");
		printf("** **\n");
		printf("** **\n");
		printf("*************《本系统由一人承办》*****************\n");
		char name_1[20] = {  "\0" };

		//分为选手和管理员
		while (menu1)
		{ 
			if (strcmp(Name, manage) == 0)
			{ 

				Menu_gaver();
				
				scanf("%d", &menu1);
				getchar();
				system("cls");
				switch (menu1) //两个界面
				{ 
				case 0:
				{ 
					exit(0);
				}
				case 1://智能
				{ 
					while (1)
					{ 
						Menu_intellent();
						scanf("%d",&menu2);
						getchar();
						switch (menu2) //两个功能
						{ 
						case 0:
						{ 
							//getchar();
							system("cls");
							break;
						}
						case 1://读取文件
						{ 
							
							system("cls");
							int num = 0;
							printf("请输入要读取选手个数:\n");
							scanf("%d", &num);
							Read_massage_file(num);
							system("pause");
							getchar();
							system("cls");
							break;

						}
						case 2://全部清理
						{ 
							getchar();

							Refresh(p_Head);
							printf("清理完毕!");
							/*system("pause"); getchar(); system("cls");*/
							break;
						}
						default:
						{ 
							printf("请输入菜单上的可操作数字.\n");
							break;
						}
						}
						if (menu2== 0)
							break;
					}
					break;
				}
				case 2://人工
				{ 
					
					while (1)
					{ 

						Menu_hand(); //九大功能
						scanf("%d", &menu2);
						getchar();

						switch (menu2)
						{ 
						case 0:
						{ 
							system("cls");
							break;
						}
						case 1: //插入
						{ 
							getchar();
							creat();//创建初期链表 及录入信xi
							printf("创建成功!\n");

							system("pause");
							getchar();
							system("cls");
							break;
						}
						case 2://删除
						{ 
							getchar();
							int index;
							printf("输入0返回!\n");
							printf("输入要删除的序号(注意不是排名):");
							scanf("%d", &index);
							getchar();
							if (index > i_count)
							{ 
								printf("序号不存在!\n");
								system("pause");
								getchar();
								system("cls");
								break;
							}
							if (index == 0)
							{ 
								system("cls");
								break;
							}
							p_Head = Delete(p_Head, index);
							printf("--已删除NO%d号选手!--\n", index);	//提示信息

							system("pause");
							getchar();
							system("cls");

							break;
						}
						case 3://尾插
						{ 

							getchar();
							creat();
							system("pause");
							getchar();
							system("cls");


							break;
						}
						case 4://修改
						{ 
							getchar();
							Modify();
							system("pause");
							getchar();
							system("cls");
							break;
						}
						case 5://原数据保存
						{ 
							getchar();
							Save_massage1(p_Head);

							system("pause");
							getchar();
							system("cls");
							break;
						}
						case 6://最终数据保存
						{ 
							getchar();
							Sort_aver(p_Head);
							Rank(p_Head);
							Save_massage2(p_Head);

							system("pause");
							getchar();
							system("cls");
							break;
						}
						case 7://全部输出
						{ 
							system("cls");
							
							Print(p_Head);


							system("pause");
							getchar();
							system("cls");
							break;
						}
						case 8://单独查找
						{ 
							getchar();
							printf("请输入要查询选手姓名:");
							scanf("%s", &name_1);
							getchar();
							p5 = Search_name(p_Head, name_1);
							if (p5 != NULL)
							{ 
								printf("姓名:%s\n", p5->name);
								printf("排名:%d\n", p5->rank);
								printf("最终成绩是:%6.2f\n", p5->aver);
							}
							else
							{ 
								printf("不存在该选手\n");

								system("pause");
								getchar();
								system("cls");
								break;
							}
						}
						case 9://说明书
						{ 
							system("cls");
							Menu_help();
							system("pause");
							getchar();
							system("cls");
							break;
						}
						default:
						{ 
							printf("请输入菜单上的可操作数字.\n");

							break;
						}


						}
						if (menu2 == 0)
							break;
					}
					break;
				}
				default:
				{ 
					printf("请输入菜单上的可操作数字.\n");
					break;
				}

				}
			}

			else
			{ 
				break;
			}
		}
		//用于判断 学生身份
		Read_file(Name);
		return 0;
	}

简单的多文件操作 用dev的话
看这个
这个

    原文作者:在机遇前,好好努力
    原文地址: https://blog.csdn.net/qq_51673383/article/details/112094006
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞