当前位置: 首页 > news >正文

C语言【文件操作】详解中

引言

        介绍和文件操作中文件的顺序读相关的函数

        看这篇博文前,希望您先仔细看一下这篇博文,理解一下文件指针和流的概念:C语言【文件操作】详解上-CSDN博客文章浏览阅读606次,点赞26次,收藏4次。先整体认识一下文件是什么,会打开和关闭文件。 关于对文件操作函数在下部分来介绍 https://blog.csdn.net/2401_88433210/article/details/146432061?spm=1011.2415.3001.10575&sharefrom=mp_manage_link

一、文件的顺序读写函数介绍

顺序读写函数(都需要头文件stdlib.h):

函数名功能(以文件为对象来说)适用于
fgetc字符输入函数所有输入流(文件流和stdin)
fputc字符输出函数所有输出流(文件流和stdout)
fgets文本行输入函数所有输入流(文件流和stdin)
fputs文本行输出函数所有输出流(文件流和stdout)
fscanf格式化输入函数所有输入流(文件流和stdin)
fprintf格式化输出函数所有输出流(文件流和stdout)
fread二进制输入函数文本输入流
fwrite二进制输出函数文本输出流

上面说的适用于所有输入流⼀般指适用于标准输入流和其他输入流(如文件输入流)

所有输出流⼀般指适用于标准输出流和其他输出流(如文件输出流)。

下面看代码理解

共四对函数,下面一个一个介绍

1.fputc和fgetc 

fputc 

      fputc函数原型:fputc - C++ Reference (cplusplus.com)

int fputc ( int character, FILE * stream );

写字符到文件中

成功写入到文件中,返回对应的ASCII值

如果写入失败,返回EOF

代码一(fputc):

        以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fputc函数写入字符a到z。

//写字符到文件中
#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	//写字符
	//fputc('a', pf);
	//fputc('b', pf);
	//fputc('c', pf);
	//fputc('d', pf);
	//fputc('e', pf);

	for (int i = 'a'; i <= 'z'; i++)
	{
		fputc(i, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:成功写入

fgetc 

        fgetc函数原型:fgetc - C++ Reference (cplusplus.com)

int fgetc ( FILE * stream );

(从文件中)读取字符成功,返回字符对应的ASCII值

如果读取失败或者遇到文件末尾,返回EOF

如果读取失败,会设置一个错误状态值------用ferror来判断(下一节讲)

如果遇到文件末尾,会设置一个遇到文件末尾的状态值------用feof来判断(下一节讲)

代码二(fgetc):

          以只读的形式'r'打开文件data.c,用fgetc函数读取字符a到z。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}

	int ch = fgetc(pf);
	printf("%c\n", ch);//a
	ch = fgetc(pf);
	printf("%c\n", ch);//b
	ch = fgetc(pf);
	printf("%c\n", ch);//c
	//会一个一个读出来
	 ch = 0;
	while ((ch = fgetc(pf)) != EOF)
	{
		printf("%c ", ch);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

 2.fputs和fgets函数

        fputs函数原型:fputs - C++ Reference (cplusplus.com)

int fputs ( const char * str, FILE * stream );

将字符串,写入到文件中(\0不会写入到文件中)
成功后,将返回非负值。
出错时,该函数返回 EOF 并设置错误指示符 (ferror)。   

fputs 

代码一(fputs):

         以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fputs函数写入字符串“hello word”。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	fputs("hello word\n", pf);


	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

fgets 

   fgets函数原型:fgets - C++ Reference (cplusplus.com)

char * fgets ( char * str, int num, FILE * stream );

(从文件中)读取(num - 1)个字符到str中。(会读取换行符\n,最后一个位置是\0)

读取成功返回字符串str的地址

如果在读取任何字符之前发生这种情况,则返回的指针为空指针(并且 str 的内容保持不变)。
如果在尝试读取字符时遇到文件结尾,则设置 eof 指示符 (feof)。
如果发生读取错误,则设置错误指示符 (ferror) 并返回 null 指针(但 str 指向的内容可能已更改)。

代码二(fgets):       

        以只读的形式'r'打开文件data.c,用fgets函数读取字符串到数组中。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20] = { 0 };
	fgets(arr, 20, pf);
	printf("%s", arr);
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

  运行结果:

调试看arr数组里面的内容: 

3. fscanf和fprintf函数

fprintf

        fprintf函数原型:fprintf - C++ Reference (cplusplus.com)

int fprintf ( FILE * stream, const char * format, ... );

        可以类比printf函数来使用,只不过多了一个写入的流对象的指针

成功后,将返回写入的字符总数。
如果发生写入错误,则设置错误指示符 (ferror) 并返回负数。
如果在写入宽字符时出现多字节字符编码错误,则 errno 设置为 EILSEQ 并返回负数。

代码一(fprintf): 

        以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fprintf函数写入数据,任何类型的数据都可以

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	char arr[20] = "hello";
	int num = 100;
	double PI = 3.14;
	fprintf(pf, "%s %d %f", arr, num, PI);

	
	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

fscanf

fscanf函数原型:fscanf - C++ 参考 (cplusplus.com)

int fscanf ( FILE * stream, const char * format, ... );

        类比scanf来使用,只不过多了一个流对象的指针

        成功后,该函数返回成功填充的参数列表的项目数。

        如果在读取时发生读取错误或到达文件末尾,则会设置正确的指示符(feof 或 ferror)。而且,如果在成功读取任何数据之前发生任何情况,则返回 EOF。

代码二(fscanf): 

        以只读的形式'r'打开文件data.c,用fscanf函数读取内容到结构体中。

struct S
{
	char arr[20];
	int num;
	double PI;
};
#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");//打开文件
	if (pf == NULL)
	{
		perror("fopen");
		return 1;
	}
	struct S s = { 0 };
	//读文件
	fscanf(pf, "%s %d %lf", s.arr, &(s.num), &(s.PI));
	printf("%s %d %lf\n", s.arr, s.num, s.PI);
	

	//关闭文件
	fclose(pf);
	pf = NULL;
	return 0;
}

运行结果:

4.fwrite和fread 

fwrite

fwrite函数原型:fread - C++ Reference (cplusplus.com)

size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

ptr   :指向要写入的元素数组的指针,转换为 const void*。

size :要写入的每个元素的大小(以字节为单位)。
count : 元素数,每个元素的大小为 size 字节。

stream:指向指定输出流的 FILE 对象的指针。

结合代码来看一下就明白了:

代码一(fwrite): 

          以只写的形式'w'打开文件data.c,没有该文件的话会自动创建一个该文件,并用fwrite函数,写入二进制数据。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "w");//打开文件
	if (pf == NULL)
	{
		perror(pf);
		return 1;
	}

	int arr[20] = { 1,2,3,4,5 };
	fwrite(arr, sizeof(arr[0]), 5, pf);


	fclose(pf);
	pf = NULL;

	return 0;
}

运行结果:

以二进制的形式来看: 

第一步:

第二步: 

第三步: (看)

fread 

fread函数原型:fread - C++ Reference (cplusplus.com)

size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

ptr   :指向要写入的元素数组的指针,转换为 const void*。

size :要写入的每个元素的大小(以字节为单位)。
count : 元素数,每个元素的大小为 size 字节。

stream:指向指定输入流的 FILE 对象的指针。

结合代码来看一下就明白了:

代码二(fread):

    以只读的形式'r'打开文件data.c,用fread函数读取数据。

#include<stdio.h>
#include<stdlib.h>
int main()
{
	FILE* pf = fopen("data.txt", "r");//打开文件
	if (pf == NULL)
	{
		perror(pf);
		return 1;
	}

	int arr[20] = { 0 };
	fread(arr, sizeof(arr[0]), 5, pf);
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", arr[i]);
	}

	fclose(pf);
	pf = NULL;

	return 0;
}

运行结果:

 二、理解函数适用的流

         对应适用于所以流的函数,其参数部分的流部分可以是文件指针FILE的指针也可以是屏幕和键盘的输入输出流即stdin 和 stdout 流。

以fprintf函数来举个例子,其他类似:

#include<stdio.h>
#include<stdlib.h>
struct S
{
	char arr[20];
	int num;
	double pai;
};
int main()
{
	struct S s = { "world", 202, 3.14 };
	fprintf(stdout, "%s %d %.2lf", s.arr, s.num, s.pai);

	return 0;
}

运行结果:

相关文章:

  • ASP.NET Web的 Razor Pages应用,配置热重载,解决.NET Core MVC 页面在更改后不刷新
  • 细说卫星导航:测距定位原理
  • Linux-Ubuntu 系统学习笔记 | 从入门到实战
  • C# 调用 VITS,推理模型 将文字转wav音频调试 -数字人分支
  • Leetcode 刷题笔记1 图论part04
  • [思考记录]两则:宏观视角、理想化
  • #echarts#折线图#饼图
  • @JsonSerialize注解
  • 机器臂运动控制算法工程师面试
  • LVGL常用功能备忘
  • STM32基础教程——定时器
  • 天梯赛 L2-013 红色警报
  • 2025海外华文新媒体高级人才研修班在广西南宁举办
  • Java实体类(Javabean)-编程规范
  • 自动学习和优化过程,实现更加精准的预测和决策的智慧交通开源了
  • 神聖的綫性代數速成例題13. 非齊次方程組解的性質、非齊次方程組解的討論
  • python:music21 构建 LSTM+GAN 模型生成爵士风格音乐
  • [笔记] TinyWebServer编译及demo运行过程
  • 什么是PHP伪协议
  • 详细解释计算机系统中的大小端
  • 武汉楼市新政:二孩、三孩家庭购买新房可分别享受6万元、12万元购房补贴
  • 全国人民代表大会常务委员会公告〔十四届〕第十号
  • 工行一季度净赚841亿元降3.99%,营收降3.22%
  • 商务部:一季度我国服务贸易较快增长,进出口总额同比增8.7%
  • 西班牙遭遇史上最严重停电,已进入国家紧急状态
  • 日韩 “打头阵”与美国贸易谈判,汽车、半导体产业忧虑重重