文件操作
基础操作
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, ...)
用法与 类似,第一个参数为文件指针,返回成功读取元素的个数,若读到文件尾(EOF)会返回EOF(一般情况下是 -1)
成功读取之后文件指针(我按照光标来理解)会向后偏移相应的位数
fprintf
函数原型
int fprintf(FILE *stream, const char *format, ...)
用法与 类似,第一个参数为文件指针
成功输出之后文件指针会向后偏移相应的位数
fgetc
函数原型
int fgetc(FILE *stream)
用法与 类似,参数为文件指针
返回文件指针后面的字符,常常需要一个字符变量接收
成功读取之后文件指针会向后偏移相应的位数
fputc
函数原型
int fputc(int char, FILE *stream)
用法与 类似,第一个参数为要输出的字符变量,第二个参数为文件指针
成功输出之后文件指针会向后偏移相应的位数
feof
函数原型
int feof(FILE *stream)
如果文件指针后面还有元素,则返回非零值,否则返回零
实际上 有时并不能达到我们理想中的效果,可以参考这篇博客
实际应用中可以利用 返回 NULL 的特性,或者使用 读取,直到读取到EOF
fgets
函数原型
char *fgets(char *str, int n, FILE *stream)
第一个参数字符指针,第二个允许读取的最大长度(要预留出空字符的位置,实际上最大长度是n - 1),第三个文件指针
如果读取成功,该函数返回相同的 str 参数。如果到达文件末尾或者没有读取到任何字符,str 的内容保持不变,并返回一个空指针。
fputs
函数原型
int fputs(const char *str, FILE *stream)
与 相比,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
如果文件以追加方式打开,那么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);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【.NET】调用本地 Deepseek 模型
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库