前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >按行读文件---->fgets函数

按行读文件---->fgets函数

作者头像
大忽悠爱学习
发布2021-03-02 15:07:41
1.2K0
发布2021-03-02 15:07:41
举报
文章被收录于专栏:c++与qt学习

函数原型:

char *fgets(char *buf, int bufsize, FILE *stream);

注意:第二个参数是最大读取字节数 参数:

*buf: 字符型指针,指向用来存储所得数据的地址。 bufsize: 整型数据,指明存储数据的大小。 stream: 文件结构体指针,将要读取的文件流。*

EOF EOF是一个宏:#define EOF -1 文件中不存在EOF,EOF是表示文件是否结束的一个状态值 EOF文件结束标识符,以\0作为结束标识符

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//按行向文件写入
void test()
{
	FILE* fp = fopen("test.txt", "w");
	if (fp == NULL)
	{
		printf("打开文件失败");
	}
	char buf[120] = "拨不通的电话\n信号丢失云层上\n孩子别紧张\n生活不是竞技场\n";
	fputs(buf, fp);
	fclose(fp);
}
//从文件中按行读取
void test01()
{
	FILE* fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		printf("打开文件失败");
		exit(1);
	}
	char buf[120];
	//feof判断读取是否到达文件结尾
	while (!feof(fp))
	{
		//每次读取文件中的一行数据
		fgets(buf, sizeof(buf), fp);
		//因为输出的时候加了\n,在输入的时候也加了\n,说以每行之间会空出一行
		//解决方法:每次循环将buf字符串倒数第二个换行符变成\0
		buf[strlen(buf) - 1] = '\0';
		printf("%s\n", buf);
	}
}
int main()
{
	test();
	test01();
	return 0;
}
在这里插入图片描述
在这里插入图片描述

问题最后多出一句重复的话,并且最后一个字是?未知符号 原因:

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

不继续读取第六行是因为上一次记载的有效数据第四行结尾存在的\0,并且\n也被替换成了\0,所以不会再将光标跳转至下一行

解决方法1:将生活不是经济场最后的\n去掉,这样光标不会移动到下一行

但是乱码还是会出现,因为最后一次循环的时候会把\0前面的场字是中文,占两个自节,而替换的\0只有一个字节,因此会出现乱码

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

解决上面问题的方法:利用fegts返回值检验是否读取到了有效内容,没有直接退出循环

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

检验是否读取到有效字符

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

下面的代码还存在小问题,因为如果用户再输入的时候没有再最后一行的场字后面加上\n,便还是存在乱码,原因还是场字为中文占据两个字节,用一个字节的\0替换会有问题

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//按行向文件写入
void test()
{
	FILE* fp = fopen("test.txt", "w");
	if (fp == NULL)
	{
		printf("打开文件失败");
	}
	char buf[120] = "拨不通的电话信号\n丢失云层上\n孩子别紧张\n生活不是竞技场\n";
	fputs(buf, fp);
	fclose(fp);
}
//从文件中按行读取
void test01()
{
	FILE* fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		printf("打开文件失败");
		exit(1);
	}
	char buf[120];
	//feof判断读取是否到达文件结尾
	while (!feof(fp))
	{
		//每次读取文件中的一行数据
		char*ret=fgets(buf, sizeof(buf), fp);
		if (ret == NULL)
		{
			break;
		}
		//因为输出的时候加了\n,在输入的时候也加了\n,说以每行之间会空出一行
		//解决方法:每次循环将buf字符串倒数第二个换行符变成\0
		buf[strlen(buf) - 1] = '\0';
		printf("%s\n", buf);
	}
}
int main()
{
	test();
	test01();
	return 0;
}
在这里插入图片描述
在这里插入图片描述

优化代码:替换feof函数 上面不写\n出现的问题,依旧会出现,把输入的数据换成英文就可以解决

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//按行向文件写入
void test()
{
	FILE* fp = fopen("test.txt", "w");
	if (fp == NULL)
	{
		printf("打开文件失败");
	}
	char buf[120] = "拨不通的电话信号\n丢失云层上\n孩子别紧张\n生活不是竞技场\n";
	fputs(buf, fp);
	fclose(fp);
}
//从文件中按行读取
void test01()
{
	FILE* fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		printf("打开文件失败");
		exit(1);
	}
	char buf[120];
	while (fgets(buf, sizeof(buf), fp))
	{
		buf[strlen(buf) - 1] = '\0';
		printf("%s\n", buf);
	}
}
int main()
{
	test();
	test01();
	return 0;
}

下面的代码才是正解,有无\n均可,直接将文件中的数据以文件中的形式读取出来

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//按行向文件写入
void test()
{
	FILE* fp = fopen("test.txt", "w");
	if (fp == NULL)
	{
		printf("打开文件失败");
	}
	char buf[120] = "拨不通的电话信号\n丢失云层上\n孩子别紧张\n生活不是竞技场\n";
	fputs(buf, fp);
	fclose(fp);
}
//从文件中按行读取
void test01()
{
	FILE* fp = fopen("test.txt", "r");
	if (fp == NULL)
	{
		printf("打开文件失败");
		exit(1);
	}
	char buf[120];
	while (fgets(buf, sizeof(buf), fp))
	{
		
		printf("%s", buf);
	}
}
int main()
{
	test();
	test01();
	return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/02/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档