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

写这篇博客原因:

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

老师力推这个功能!!

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

喔对了。系统可以使用特殊符号 记得自己尝试一下
在这里插入图片描述

代码可以根据函数名自取

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

进入正题:

先看效果 是不是你们想要的。先看效果 是不是你们想要的。
这是写出后的两个文件对比;
左边是录入原数据,右边是排名计算后写入的数据。

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

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);
	}

首先看这个格式:如何实现?
在这里插入图片描述

先将你的格式写入字符串 ,用fprintf库函数先将你的格式所在的字符数组写入文件,然后在写入链表内容数据。
(不用fwrite是因为这个是二进制写入 写int 数据会乱码 所以没有深入了解)
在这里插入图片描述

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语言代码源文件在一起哦!一个人多孤单!)**
在这里插入图片描述
文件比较乱哈哈
在这里插入图片描述

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.文件内容开头是我们的格式 并不需要读取,那么怎么跳过?
在这里插入图片描述
这里利用fseek库函数
fseek(fp,173, 0);//跳过开头格式
fseek(文件指针,跳过的字节数,从哪里开始跳)
文件指针 经过上面两个信息储存大家应该了解了,
那么字节数怎么把控?一个一个数?其中’+’’-'代表往前往后跳。
我们用的是+
往哪里跳,0 开头,1当前所在位置 这个目前还没用过,2从尾开始跳
我们用的是0 开头

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

在这里插入图片描述
在这里插入图片描述
都秒懂是吧???
不过要注意
这里我读取的是我的第二个文件
两个文件的格式不一样哦在这里插入图片描述
在这里插入图片描述
多一个average
2.如何正确读取文件数据到变量;
我这里写入的时候就是用的链表数据写入的
所以我定义了一个结构体 类型 不含 next指针
在这里插入图片描述
用第二种;

看代码:

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

下面将我的整个代码给出来吧。
我是用vs2019 写的 忽略scanf警告
如何忽略?
看图 两种方法
在这里插入图片描述
右击源文件 点属性

在这里插入图片描述
在这里插入图片描述

在预处理器定义内输入 _CRT_SECURE_NO_WARNINGS

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

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

例如:
在这里插入图片描述

在这里插入图片描述

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

评分管理系统要求如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#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"
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在机遇前,好好努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值