文件操作

基础操作

fopen

函数原型

FILE*fopen(const char *path,const char*mode)
文件打开成功会返回文件类型指针,否则返回NULL
path 为文件路径,mode 为文件打开方式,包括 r, w, a, r+, w+, a+, rb, wb, ab 等
打开方式详情参照这篇博客

fclose

函数原型

int fclose(FILE*f);
关闭文件是一个良好的编程习惯,可以释放文件相关的资源,避免出现文件句柄泄漏等问题。

fscanf

函数原型

int fscanf(FILE *stream, const char *format, ...)
用法与 scanf 类似,第一个参数为文件指针,返回成功读取元素的个数,若读到文件尾(EOF)会返回EOF(一般情况下是 -1)
成功读取之后文件指针(我按照光标来理解)会向后偏移相应的位数

fprintf

函数原型

int fprintf(FILE *stream, const char *format, ...)
用法与 printf 类似,第一个参数为文件指针
成功输出之后文件指针会向后偏移相应的位数

fgetc

函数原型

int fgetc(FILE *stream)
用法与 getchar 类似,参数为文件指针
返回文件指针后面的字符,常常需要一个字符变量接收
成功读取之后文件指针会向后偏移相应的位数

fputc

函数原型

int fputc(int char, FILE *stream)
用法与 putchar 类似,第一个参数为要输出的字符变量,第二个参数为文件指针
成功输出之后文件指针会向后偏移相应的位数

feof

函数原型

int feof(FILE *stream)
如果文件指针后面还有元素,则返回非零值,否则返回零
实际上 feof 有时并不能达到我们理想中的效果,可以参考这篇博客
实际应用中可以利用 fgets 返回 NULL 的特性,或者使用 fgetc 读取,直到读取到EOF

fgets

函数原型

char *fgets(char *str, int n, FILE *stream)
第一个参数字符指针,第二个允许读取的最大长度(要预留出空字符的位置,实际上最大长度是n - 1),第三个文件指针
如果读取成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。

fputs

函数原型

int fputs(const char *str, FILE *stream)
puts 相比,fputs 并不会在末尾添加换行符,但是读取到换行符会照样输出

rewind

函数原型

void rewind(FILE *stream)
将文件指针拨回到文件开头

小练习

【问题描述】编写一个程序,交替合并两个文件a.txt和b.txt中的行,并将结果写入c.txt中。如果一个文件的行数少于另一个文件,那么大文件中剩余的行数应该简单地复制到c.txt中。

点击查看代码
#include "stdio.h"
#include "string.h"
char s[500];
int flag = 0;
int main()
{
	FILE* fa = fopen("a.txt", "r");
	FILE* fb = fopen("b.txt", "r");
	FILE* fc = fopen("c.txt", "w");
	while (1)
	{

		FILE* f = flag == 0 ? fa : fb;
		if (!fgets(s, 500, f))break;
		fputs(s, fc);
		flag = (flag + 1) % 2;
	}
	while (fgets(s, 500, fa))
	{
		fputs(s, fc);
	}
	while (fgets(s, 500, fb))
	{
		fputs(s, fc);
	}
}


参考博客

https://blog.csdn.net/ZJRUIII/article/details/120552735
https://blog.csdn.net/kangjianwei101/article/details/50517536

UPD

2024/11/26
如果文件以追加方式打开,那么fputs等输出函数指针都会是文件末尾,不论是否使用了rewind

点击查看代码
void savedata(int raw_data[],int raw_data_length,int encoded_data[],int encoded_data_length)
{
	FILE* f = fopen("data_packages.txt", "a+");
	fputs("raw data\n",f);
	for (int i = 0; i < raw_data_length; ++i)
	{
		fprintf(f, "%d ", raw_data[i]);
	}
	fputc('\n', f);
	fputs("encoded data\n", f);
	for (int i = 0; i < encoded_data_length; ++i)
	{
		fprintf(f, "%d ", encoded_data[i]);
	}
	fputc('\n', f);
	rewind(f);
	int num = 0;
	fscanf(f, "%d", &num);
	num++;
	rewind(f); fflush(f);
	fputs("                          ", f);//覆盖掉原有数据
	rewind(f); fflush(f);
	fprintf(f, "%d", num);
}
代码的本意是在新增数据包后更改文件开头num的值,然而fputs,fprintf会使指针重新回到文件末尾,无法有效更改num的值 目前还没有找到合理的解决方法
posted @   Chano_sb  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示