尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

C语言:文件操作

C语言:文件操作
📅 发布时间:2026/7/26 7:22:40

1. 为什么使用文件
2. 什么是文件
3. 二进制文件和文本文件
4. 文件的打开和关闭
5. 文件的顺序读写
6. 文件的随机读写
7. 文件缓冲区
8.更新文件

1. 为什么使用文件

文件的核心作用就是:把数据从易失的内存,存到持久的硬盘里,程序退出了数据也不会丢。

2. 什么是文件
在程序设计中,我们⼀般谈的文件有两种:程序文件、数据文件
2.1程序文件

程序文件就是和 “程序本身”相关的文件,比如.c源代码、编译生成的.obj目标文件、最终的.exe可执行文件,这些都是用来构成和运行程序的。

2.2数据文件

数据文件就是程序运行时用来读写数据的文件,内容不一定是代码,比如程序运行需要从中读取数据的文件,或者输出内容的文件,程序从里面读数据,也能把结果写到里面去。

2.3文件名

文件名其实是文件的唯一标识,用来定位和区分不同文件,完整的标识包含三部分:
文件路径:文件在磁盘上的位置,比如 c:\code\
文件名主干:文件的名字,比如 test
文件后缀:表示文件类型,比如 .txt

举个例子:c:\code\test.txt
路径:c:\code\
主干:test
后缀:.txt

3. 二进制文件和文本文件
存储方式存储规则示例(整数10000)占用空间
文本文件(ASCLL形式)所有数据都按 ASCII 字符存储,数值会被拆成字符'1' '0' '0' '0' '0'5 字节
二进制文件直接把内存中的二进制数据原封不动写入文件00000000 00000000 00100111 000100004 字节(int 类型占 4 字节)

关键区别:
文本文件:人能直接看懂(比如用记事本打开),但会额外占用空间,读写时需要转换。
二进制文件:和内存中的数据结构完全一致,读写速度快,空间更省,但人无法直接看懂。

3.1整数10000的两种存储方式

1.内存中的形式10000 作为 int 类型,在内存中是 4 字节的二进制:00000000 00000000 00100111 00010000(十进制转二进制结果)。
2.ASCII 形式(文本文件)会把 10000 拆成 5 个字符:'1' '0' '0' '0' '0',每个字符的 ASCII 码是:
'1' → 00110001(49)
'0' → 00110000(48)所以文件里会存这 5 个字节:00110001 00110000 00110000 00110000 00110000,共 5 字节。
3.二进制形式(二进制文件)直接把内存中的 4 字节原封不动写入文件,文件里就是:00000000 00000000 00100111 00010000,共 4 字节。用 VS 的二进制编辑器打开,会看到十六进制:00 00 27 10(和二进制一一对应)。

3.2演示代码解析
#include <stdio.h> int main() { int a = 10000; FILE* pf = fopen("test.txt", "wb"); // "wb" 表示:以二进制模式写文件 fwrite(&a, 4, 1, pf); // 从变量a的地址开始,写4个字节,写1次 fclose(pf); pf = NULL; return 0; }

fopen的 "wb" 模式是关键:w 表示写,b 表示二进制(binary),不加 b 就是文本模式。
fwrite直接把 a 的内存数据原封不动写入文件,所以生成的是二进制文件。

我们发现文件会产生乱码的情况,这是因为文本文档中不是在二进制文件中,并且直接打开是会产生弹窗。

这时我们就要改变它的打开方式,将其改为二进制的打开方式

这时生成结果就是下面的二进制序列

3.3VS 中查看二进制文件的方法

1.在 VS 的「解决方案资源管理器」中,右键 test.txt。
2.选择「打开方式」。
3.在弹出的窗口中,选择「二进制编辑器」。
4.打开后就能看到文件的十六进制内容:00 00 27 10,和我们前面分析的一致。

4. 文件的打开和关闭
4.1流和标准流
4.1.1流

1流是 C 语言中对外部设备(文件、键盘、屏幕等)数据交互的抽象概念,可以理解为数据流动的通道。
2.所有输入输出操作(如键盘输入、屏幕打印、文件读写),都是通过 “流” 来完成的。
3.流操作自带缓冲区,目的是减少直接读写硬盘的次数,提高效率。

4.1.2标准流

C 程序启动时,会自动打开 3 个流,无需手动 fopen:

流名含义用途
stdin标准输入流从键盘读取数据,scanf 函数使用它
stdout标准输出流向屏幕打印数据,printf 函数使用它
stderr标准错误流向屏幕输出错误信息

这三个流的类型都是 FILE*(文件指针),和文件操作的指针是同一种类型。

4.2文件指针

每个被打开的文件,都会在内存中创建一个文件信息区(FILE 结构体变量),存储文件名、状态、读写位置等信息。
FILE* 就是指向这个结构体的指针,我们通过它来间接操作文件。
不同编译器的 FILE 结构体细节不同(如 VS 的 struct _iobuf),但用法一致,开发者无需关心内部实现。

4.3文件的打开和关闭
文件在读写之前应该先打开文件,在使用结束之后应该关闭文件。
同时ANSI C 规定使用fopen函数来打开文件,fclose 来关闭文件。
4.3.1fopen
//打开⽂件 FILE * fopen ( const char * filename, const char * mode );

1.参数:
filename:要打开的文件名(可以是相对路径或绝对路径)。
绝对路径

"盘符:/文件夹/文件名.后缀" "E:/project/data.txt"

相对路径

同级:直接写文件名 子级:文件夹/文件名 上级:../文件名

mode:文件打开方式(核心参数,决定读写权限和文件类型)。

2.返回值:
成功:返回一个 FILE* 类型的指针,指向该文件的信息区。
失败:返回 NULL,必须做判空处理,否则会引发程序崩溃。

#include<stdio.h> int main() { FILE* pf= fopen("test.txt","r"); if (pf == NULL) { perror("fopen"); return 1; } //读文件 //关闭为文件 fclose(pf); pf = NULL; }

常用mode 对照表

模式含义文本不存在时文本存在时
“r”
只读(文本文件)报错打开,只读
“w”只写(文本文件)创建新文件清空原有内容,只写
“a”追加(文本文件)创建新文件在文件末尾追加数据
“rb”只读(文本文件)报错打开,只读
“wb”只写(文本文件)创建新文件清空原有内容,只写
“ab”追加(文本文件)创建新文件在文件末尾追加数据
“r+”读写(文本文件)报错打开,可读写
“w+”读写(文本文件)创建新文件清空原有内容,可读写
“a+”读写(文本文件)创建新文件末尾追加 + 读
4.3.2fclose
int fclose(FILE *stream);

功能:关闭文件,刷新缓冲区,释放文件信息区的资源。
返回值:成功返回 0,失败返回 EOF。
!!!注意:文件使用完必须关闭,否则会导致数据未写入、资源泄漏。关闭后建议将指针置为 NULL,避免野指针。

代码演示:
#include <stdio.h> int main() { // 1. 打开文件,只读模式 FILE* fp = fopen("test.txt", "r"); if (fp == NULL) // 必须判空! { perror("fopen"); // 打印错误信息 return 1; } printf("文件打开成功,可以进行读写操作\n"); // 2. 关闭文件 fclose(fp); fp = NULL; // 置空,避免野指针 return 0; }
4.4避坑指南与关键细节

1.必须判空:fopen 失败会返回 NULL,如果直接使用空指针操作文件,会导致程序崩溃。
2.关闭文件:不关闭文件会导致缓冲区数据未写入硬盘,文件内容丢失;同时占用系统资源。
3.文本和二进制模式:
文本模式下,Windows 系统会自动将 \n 转换为 \r\n 写入文件,读取时再转换回来。
二进制模式下,数据原封不动读写,不会做任何转换,适合图片、视频等非文本数据。
4.路径问题:Windows 下路径分隔符是 \,但 C 语言中 \ 是转义字符,所以路径要写成 D:\\test.txt 或 D:/test.txt。
5."w" 模式会清空文件:使用 "w" 或 "wb" 打开已存在的文件时,文件内容会被直接清空,操作前一定要确认。

5.文件的顺序读写
5.1函数总览
函数名功能适用范围
fgetc从输入流读取单个字符所有输入流(文件、stdin)
fputc从输出流读取单个字符所有输出流(文件、stdin)
fgets从输入流读取字符串所有输入流
fputs从输出流读取字符串所有输出流
fscanf从输入流读取格式化数据所有输入流
fprintf从输出流读取格式化数据所有输出流
fread读取一块二进制数据仅文件输入流
fwrite写入一块二进制数据仅文件输出流
5.2字符读写函数
5.2.1fputc
int fputc ( int character, FILE * stream );

1.参数:
character:待写入字符
stream:文件指针 / 输出流(stdout--屏幕)
2.返回值:成功返回写入的字符(int 型);失败返回EOF(-1)

代码演示:写入单个字符

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "w"); // w模式:清空原有内容,新建文件写入 if(fp == NULL) { perror("fopen"); return 1; } fputc('a', fp); fputc('b', fp); fputc('c', fp); fclose(fp); // 关闭文件 fp = NULL; // 置空避免野指针 return 0; }

此时test.txt文件中将是abc

代码演示2:循环写入 a-z 所有字符

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "w"); if(fp == NULL) { perror("fopen"); return 1; } int ch = 0; for(ch = 'a'; ch <= 'z'; ch++) { fputc(ch, fp); } fclose(fp); fp = NULL; return 0; }

此时test.txt文件中将是a到z所有字符

5.2.2fgetc
int fgetc ( FILE * stream );

参数:stream:文件指针 / 输入流(stdin--键盘)
返回值:成功返回读取的字符(int 型);读到末尾 / 出错返回EOF(-1)

代码演示1:读取文件前 10 个字符并打印前 10 个字符

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "r"); // r模式:只读 if(fp == NULL) { perror("fopen"); return 1; } int i = 0; for(i = 0; i < 10; i++) { int c = fgetc(fp); fputc(c, stdout); // stdout:标准输出(控制台) } fclose(fp); fp = NULL; return 0; }

代码演示2:读取文件中所有数据并打印文件中所有数据

#include<stdio.h> int main() { FILE* pf = fopen("test.tst", "r");//读文件 if (pf == NULL) { perror("fopen"); return 1; } int ch = 0; while ((ch = fgetc(pf)) != EOF) { printf("%c",ch); } fclose(pf);//关闭文件 pf = NULL; return 0; }
5.2.3feof和ferror

feof

int feof ( FILE * stream ); //检测stream指针指向的流是否遇到⽂件末尾

参数:stream:文件指针
返回值:到文件末尾返回非 0;未到末尾返回 0

ferror

int ferror ( FILE * stream ); //检测stream指针指向的流是否发⽣读/写错误

参数:stream:文件指针
返回值:读写出错返回非 0;无错误返回 0

代码演示1:feof 判断文件末尾

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "r"); if(fp == NULL) { perror("fopen"); return 1; } int c = 0; while((c = fgetc(fp)) != EOF) // 循环读取,直到末尾 { fputc(c, stdout); } if(feof(fp)) printf("读到文件末尾\n"); else if(ferror(fp)) printf("读取出错\n"); fclose(fp); fp = NULL; return 0; }

代码演示2:ferror 判断读写错误

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "w"); // 只写模式,不能读,会触发错误 if(fp == NULL) { perror("fopen"); return 1; } int c = fgetc(fp); // 尝试读取,触发错误 if(c == EOF) { if(ferror(fp)) printf("读取出错\n"); } fclose(fp); fp = NULL; return 0; }
5.3字符串读写函数
5.3.1fputs
int fputs ( const char * str, FILE * stream );

参数:
str:待写入字符串
stream:文件指针 / 输出流
返回值:成功返回非负数;失败返回EOF(-1)

代码演示1:写入字符串

//fputs输入字符串到文件中 #include<stdio.h> int main() { FILE* pf = fopen("test.tst", "w");//写文件 if (pf == NULL) { perror("fopen"); return 1; } fputs("hello", pf); fputs("world", pf); fclose(pf);//关闭文件 pf = NULL; return 0; }

此时test.txt文件中将是helloworld

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

参数:
str:存储读取内容的字符数组
num:最大读取字符数(包含结尾的\0,实际最多放num-1个字符)
stream:文件指针 / 输入流
返回值:成功返回str 地址;末尾 / 出错返回NULL

代码演示1:读取文件两行内容

#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "r"); if(fp == NULL) { perror("fopen"); return 1; } char arr1[10] = {0}; char arr2[10] = {0}; fgets(arr1, sizeof(arr1), fp); // 读取第一行 fgets(arr2, sizeof(arr2), fp); // 读取第二行 printf("%s", arr1); printf("%s", arr2); fclose(fp); fp = NULL; return 0; }

或者运用循环

//用fgets读取文件 #include<stdio.h> int main() { FILE* pf = fopen("test.tst", "r");//写文件 if (pf == NULL) { perror("fopen"); return 1; } char arr[20] = "-----------"; /*fgets(arr, 5, pf);*///abcd\0 //如果有多行数据 运用循环 while ((fgets(arr, 20, pf)) != NULL) { printf("%s ", arr); } fclose(pf);//关闭文件 pf = NULL; return 0; }
5.4格式化读写函数
5.4.1fprintf
int fprintf ( FILE * stream, const char * format, ... ); //类⽐printf函数学习

参数:
stream:文件指针 / 输出流
format:格式字符串
...:可变参数(待写入数据)

返回值:成功返回写入字符个数;失败返回负数

代码演示1:写入结构体数据

//用fprintf写入文件 #include<stdio.h> struct Stu { char name[20]; int age; float score; }; int main() { struct Stu s = { "zhangsan", 20, 95.5f }; FILE* pf = fopen("test.tst", "w");//写文件 if (pf == NULL) { perror("fopen"); return 1; } fprintf(pf,"名字:%s 年龄;%d 成绩:%f\n",s.name ,s.age,s.score ); fclose(pf);//关闭文件 pf = NULL; return 0; }

此时test.txt文件中将是zhangsan", 20, 95.5f

5.4.2fscanf
int fscanf ( FILE * stream, const char * format, ... ); //类⽐scanf函数来学习

参数:
stream:文件指针 / 输入流
format:格式控制字符串(同scanf)
...:变量地址列表

返回值:成功函数返回成功填充到参数列表中的项数。

如果在成功读取任何数据之前发生:
1.发生读取错误,会在对应流上设置错误指示符,则返回EOF。
2.到达文件末尾,会在对应流上设置⽂件结束指⽰符,则返回EOF。

代码演示1:读取文件中结构体数据

//用fscanf读取数据 #include<stdio.h> struct Stu { char name[20]; int age; float score; }; int main() { struct Stu s = { "zhangsan", 20, 95.5f }; FILE* pf = fopen("test.tst", "w");//写文件 if (pf == NULL) { perror("fopen"); return 1; } fscanf(pf, "名字:%s 年龄:%d 成绩:%f", s.name, &(s.age), &(s.score)); fprintf(stdout, "名字:%s 年龄:%d 成绩:%.2f\n", s.name, s.age, s.score); fclose(pf);//关闭文件 pf = NULL; return 0; }
5.5sprintf 和 sscanf
5.5.1sprintf
int sprintf ( char * str, const char * format, ... );

功能
把格式化数据写入字符数组(字符串),相当于把 printf 的输出从屏幕改成内存字符串。
参数
str:字符数组指针,存储生成的字符串(空间要足够,防止溢出)
format:格式字符串(%d、%f、%s 等)
...:可变参数,对应格式的数据
返回值
成功:返回写入的字符数(不含末尾\0)
失败:返回负值

示例(核心就是把内容转换成字符串 并存放)

struct Stu s = {"zhangsan", 100, 85.5f}; char arr[100] = {0}; sprintf(arr, "%s %d %.1f", s.name, s.age, s.score);

这个代码就是将结构体s中的内容转换成一个字符串

5.5.2sscanf
int sscanf ( const char * str, const char * format, ...);

功能
从字符串里读取格式化数据,相当于把 scanf 的输入从键盘改成内存字符串。
参数
str:源字符串(数据来源)
format:格式字符串
...:变量地址列表
返回值
成功:返回成功读取赋值的参数个数
失败 / 到末尾:返回 EOF(-1)

示例(核心是从字符串中解析出一个格式化的数据)

char str[] = "zhangsan 100 85.5"; struct Stu s = {0}; sscanf(str, "%s %d %f", s.name, &s.age, &s.score);

把sprintf和sscanf结合起来使用

//ssprintf //把格式化数据 转换成字符串并存放在内存中 #include<stdio.h> struct Stu { char name[20]; int age; float score; }; int main() { struct Stu s = { "zhangsan", 20, 95.5f }; char arr1[30] = { 0 }; sprintf(arr1, "%s %d %.2f", s.name, s.age, s.score);//存放进字符串内存区 printf("%s\n", arr1); //sscanf //从arr1中解析处一个结构体数据 struct Stu t = { 0 }; sscanf(arr1, "%s %d %f", t.name, &(t.age), &(t.score)); sprintf(stdout, "%s %d %.2f", s.name, s.age, s.score);//存放进字符串内存区 return 0; }

此时输出结果是下面这张图

5.5.3 6组格式化函数总对比
函数作用操作对象
scanf格式化输入标准输入 stdin
printf格式化输出标准输出 stdout
fscanf格式化输入文件流 / stdin
fprintf格式化输出文件流 / stdout
sprintf格式化输出内存字符串

sscanf

格式化输入内存字符串
5.6二进制批量读写函数
5.6.1fwrite(从文件中读取数据到格式化变量中)
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );

参数
ptr:待写入数据的内存首地址
size:单个数据的字节大小
count:要写入的数据个数
stream:文件指针

示例:写入数组二进制数据

//fwrite的使用 #include<stdio.h> struct Stu { char name[20]; int age; float score; }; int main() { struct Stu s = { "zhangsan", 20, 95.5f }; FILE* pf = fopen("test.tst", "wb");//写二进制文件 if (pf == NULL) { perror("fopen"); return 1; } //写一个结构体类型的内容 到文件中去 fwrite(&s, sizeof(struct Stu), 1, pf); fclose(pf); pf = NULL; return 0; }

5.6.2fread 二进制读取(从文件中读取数据到格式化变量中)
size_t fread ( void * ptr, size_t size, size_t count, FILE * stream );

功能:批量写二进制
参数:const void* buf, size_t size, size_t count, FILE* stream
返回:实际写入的块数

示例:读取二进制结构体数据

//fread读取二进制数据 #include<stdio.h> struct Stu { char name[20]; int age; float score; }; int main() { struct Stu s = { 0 }; FILE* pf = fopen("test.tst", "rb");//读取二进制文件 if (pf == NULL) { perror("fopen"); return 1; } //读取文件中的数据 fread(&s, sizeof(struct Stu), 1, pf); printf("%s %d %.2f\n", s.name, s.age, s.score); fclose(pf); pf = NULL; return 0; }

此时输出结果是

5.7核心编码规范

1.打开文件必须判断NULL,用perror("fopen")打印错误
2.文本模式:r/w/a;二进制模式:rb/wb/ab
3.用完必须fclose(fp); fp=NULL;
4.读取后用feof、ferror判断状态

6. 文件的随机读写
6.1fseek(移动文件指针)
int fseek ( FILE * stream, long int offset, int origin );

功能:定位文件指针,实现随机读写
参数
stream:文件指针
offset:偏移量(正数向后、负数向前、0 不动)
origin:基准位置
1.SEEK_SET:文件开头
2.SEEK_CUR:当前指针位置
3.SEEK_END:文件末尾
返回值:成功返回0;失败返回非 0(-1)
!!!注意:二进制文件可随意偏移;文本文件仅支持SEEK_SET或ftell返回值偏移

//用fseek定位文件指针实现随机打印 //文件中是 abcdefghi #include<stdio.h> int main() { FILE* fp = fopen("test.txt", "r"); if (fp == NULL) { perror("fopen"); return 1; } int c = fgetc(fp);//a fputc(c, stdout);//使用fputc在标准输入流上打印字符 //定位文件指针 fseek(fp, 5, SEEK_SET);//从首个开始定位 向右5个偏移量 fseek(fp, 4, SEEK_CUR);//这是从a开始定位 向右4个偏移量 fseek(fp, -4, SEEK_END);//这是从末尾开始定位 向左4个偏移量 c = fgetc(fp); fputc(c, stdout);//f fclose(fp); fp = NULL; return 0; }

此时test.txt文件中将是abcdefghi

标准输出的结果是af

6.2ftell
long int ftell ( FILE * stream );

功能:返回文件指针相对于文件开头的字节偏移量
参数:stream:文件指针
返回值:成功返回字节数;失败返回-1L
用途:常和fseek配合,计算文件大小

fseek(fp,0,SEEK_END); long size=ftell(fp); // 得到文件总字节大小
6.2.1fseek和ftell的共同使用
//fseek和 ftell的共同使用 #include<stdio.h> int main() { FILE* fp = fopen("test.txt", "r"); if (fp == NULL) { perror("fopen"); return 1; } int c = fgetc(fp); fputc(c, stdout);//输出a int pos = ftell(fp);//这里记录的是b相对于起始位置的偏移量1 //定位文件指针 fseek(fp, 4, SEEK_CUR); c = fgetc(fp); fputc(c, stdout);//这里的是f(相对b往后偏移4) fseek(fp, pos, SEEK_SET);//这里回到初始 偏移量为1 c = fgetc(fp); fputc(c, stdout);//这里就是b fclose(fp); fp = NULL; return 0; }

输出结果如下

其中pos记录了第一次的字节数(移动偏移量),用于最后打印b时从f返回到起点

!!!每次移动后都想打印,就要重新用fgetc和fputc

6.3rewind
void rewind ( FILE * stream );

功能:文件指针重置到文件开头
关键区别
rewind(fp):移动指针 + 清除错误标志、文件末尾标志

fseek(fp,0,SEEK_SET):只移动指针,不清除标志

接着上面的代码用rewind回到起始位置 fputc(c, stdout);//这里就是b rewind(fp);//回到起始位置 c = fgetc(fp); fputc(c, stdout);//这里就是a fclose(fp); fp = NULL; return 0;

输出结果如下

7. 文件缓冲区
7.1文件缓冲区概念

ANSI C 规定:系统自动在内存给每个打开的文件开辟一块缓冲区
输出:程序数据 → 输出缓冲区 → 缓冲区满 / 刷新 → 写入硬盘
输入:硬盘数据 → 输入缓冲区 → 程序读取
作用:减少磁盘 IO,提升读写效率

7.2 fflush 函数(强制刷新缓冲区)
int fflush ( FILE * stream );

功能
输出流:强制把缓冲区数据立刻写入硬盘
输入流:行为不标准,一般不用
stream=NULL:刷新所有打开的输出流
参数
stream:文件指针 / stdout
返回值
成功输出0 失败输出EOF

刷新缓冲区的 4 种方式
缓冲区写满,自动刷新
调用 fflush(fp),手动强制刷新
调用 fclose(fp) 关闭文件,自动刷新
程序正常结束,自动刷新

核心结论
文件操作必须刷新缓冲区或关闭文件,否则数据可能只在内存,没写到硬盘。

示例代码

FILE* pf = fopen("test.txt", "w"); fputs("abcdef", pf); fflush(pf); // 强制写入磁盘 fclose(pf);
8.更新文件
在文件的打开模式中有三种方式值得注意,分别是: "r+", "w+", "a+"。
行为"r+""w+""a+"
解释可读/可写可读/可写可读/可写
文件不存在时打开失败自动创建新文件自动创建新文件
文件存在时保留内容清空内容保留内容
初始文件指针位置文件开头文件开头文件末尾
写入是否覆盖所有数据是(可定位覆盖)是(内容已清空,从头写入)否(默认是在文件末尾写数据)
典型用途修改文件部分内容创建新文件或完全重写旧文件在文件末尾追加数据,比如记录日志
关键要点:
1. 在写完文件后,要继续读文件的时候,在读取之前⼀定要使用 fflush() 刷新文件缓冲区,或者使用 fseek() , rewind() 重新定位文件指示器的位置。
2. 在读完文件后,需要继续写文件之前,在写文件之前,使⽤ fseek() , rewind() 重新定位文件指示器的位置。
#include <stdio.h> int main() { FILE* fp = fopen("test.txt", "w+"); if (fp == NULL) { perror("fopen for w+"); return 1; } //写abcdefghi到⽂件中 fputs("abcdefghi", fp); //刷新缓冲区,保证数据写⼊⽂件 fflush(fp); //要读取数据b字符,先定位⽂件指针 fseek(fp, 1, SEEK_SET); int ch = fgetc(fp);//读取字符 printf("%c\n", ch); //在b的位置开始写⼊hello fseek(fp, -1, SEEK_CUR); //解释:因为前⾯读取⼀个字符后,⽂件指⽰器现在指向了c,需要从当前位置退回⼀个字符fputs("hello", fp); //关闭⽂件 fclose(fp); fp = NULL; return 0; }

相关新闻

  • 大模型推理优化:动态计算图与混合精度实战
  • 终极指南:如何通过开源工具Wand-Enhancer实现专业版功能解锁
  • YOLOv5在农业植物检测中的优化与应用实践

最新新闻

  • C++异常处理:从语法到RAII的健壮编程实践
  • 蔚蓝档案鼠标指针主题:3分钟打造个性化二次元桌面体验
  • 基于HuggingFace的多选题问答技术实践与优化
  • AI模拟痛苦体验:技术架构与商业应用解析
  • 基于YOLO与DeepSeek的智能跌倒检测系统开发实践
  • 电商智能客服多智能体系统架构与优化实践

日新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

周新闻

  • 大连理工大学与东京大学联手打造的“主动型AI助手“
  • 170.2026年国家级科研瓶颈:超精密单点金刚石切削(SPDT)光学表面生成
  • SongBloom:革命性歌曲生成框架深度解析——如何通过交织自回归与扩散模型创作完整音乐

月新闻

  • 2026年6月公司网站搭建最新热门渠道测评:四大低成本/零代码平台对比+避坑
  • 【Linux】Linux arm 编译QT程序,出现expected “}“报错
  • 【MATLAB例程】四基站二维AOA定位与距离辅助增强对比仿真。基于角度观测和测距修正的固定目标平面定位精度分析

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号