嵌入式学习day23-----文件编程
·
一、标准 IO 核心函数(文件操作)
学习 Linux 函数的核心方法:用好man手册,重点看NAME(功能)、SYNOPSIS(头文件 + 函数原型)、RETURN VALUE(返回值)。
1. 文件打开:fopen
FILE *fopen(const char *pathname, const char *mode);
- 功能:打开指定文件,并关联一个流指针,后续通过流指针操作文件;
- 参数:
pathname:要打开的文件名(字符串形式,如 "test.txt");mode:打开模式(核心,决定文件的读写权限);- 返回值:成功返回流指针(FILE *),失败返回
NULL,且系统会设置errno。
核心打开模式说明
r:只读,文件必须存在,不存在则报错;r+:读写,文件必须存在,不存在则报错;
w:只写,文件存在则清空,不存在则创建;w+:读写,文件存在则清空,不存在则创建;
a:追加写,文件存在则末尾追加,不存在则创建;a+:追加读 / 写,文件存在则末尾追加,不存在则创建。
2. 错误信息打印:perror
void perror(const char *s);
- 功能:根据
errno自动打印对应的错误原因,配合fopen等函数的失败判断使用; - 参数:自定义的错误提示信息(字符串);
- 打印效果:
自定义信息: 系统错误原因(无需手动加\n,函数自动换行); - 示例:
perror("fopen fail"),失败时输出fopen fail: No such file or directory。
3. 文件关闭:fclose
int fclose(FILE *stream);
- 功能:关闭流指针,释放文件相关资源,必须执行,否则会造成资源泄漏;
- 参数:
stream:要关闭的流指针; - 返回值:成功返回 0,失败返回
EOF(宏,值为 - 1),且设置errno。
4. 字符级读写:fgetc /fputc
读字符:fgetc
int fgetc(FILE *stream);
- 功能:将一个字符写入指定流中;
- 参数:
c为要写入的字符(ASCII 码),stream为目标流; - 返回值:成功返回写入的字符,失败返回
EOF。
适用场景:逐字符处理文件,可处理文本文件和二进制文件(无格式限制),缺点是效率较低。
5. 字符串级读写:fgets /fputs
读字符串:fgets
char *fgets(char *s, int size, FILE *stream);
- 功能:从流中读取数据,最多读取 size-1 个字符,自动在末尾添加
'\0'(字符串结束符); - 参数:
s:存储读取数据的字符数组;size:读取的最大字节数;stream:源文件流;
- 返回值:成功返回
s,失败 / 到达文件末尾返回NULL; - 读取结束条件(满足其一即停止):
- 读到文件末尾(EOF);
- 读到换行符
\n(\n会被保留在字符数组中); - 读满
size-1个字符。
- 从键盘读取字符串时,用
fgets(buf, sizeof(buf), stdin)替代gets(buf)(gets存在缓冲区溢出风险)。
写字符串:fputs
int fputs(const char *s, FILE *stream);
- 功能:将字符串写入指定流中;
- 参数:
s为要写入的字符串,stream为目标流; - 返回值:成功返回非负数,失败返回
EOF; - 注意:写入时不会输出
'\0',遇到'\0'则停止写入。
适用场景:处理文本文件,不适合二进制文件(二进制文件中含'\0',会导致 fputs 提前停止)。
6. 块 / 对象级读写:fread /fwrite(二进制读写)
最常用的高效读写方式,按固定大小的元素读写,适合文本文件和二进制文件,尤其适合处理结构体等固定格式的数据。
读数据:fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:从流中读取
nmemb个元素,每个元素大小为size字节,保存到ptr指向的空间; - 参数:
ptr:存储数据的缓冲区地址(void*,可接收任意类型);size:单个元素的字节大小;nmemb:要读取的元素个数;stream:源文件流;
- 返回值:成功返回实际读取的元素个数,失败 / 到达文件末尾返回 0
写数据:fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- 功能:将
ptr指向的空间中,nmemb个大小为size的元素写入指定流; - 参数:同 fread,
ptr为待写入数据的缓冲区地址; - 返回值:成功返回实际写入的元素个数,失败返回 0。
7. 格式化输出:fprintf /sprintf
文件格式化输出:fprintf
int fprintf(FILE *stream, const char *format, ...);
- 功能:将格式化的数据写入指定流(文件 / 标准流),是
printf的文件版; - 示例:
fprintf(fp, "num = %d, time = %s\n", 1, "2025-01-01");、fprintf(stdout, "a = %d\n", a);(等价于printf)。
字符串格式化输出:sprintf
int sprintf(char *str, const char *format, ...);
- 功能:将格式化的数据写入字符数组,生成指定格式的字符串;
- 示例:
sprintf(buf, "name: %s, age: %d", "zhangsan", 18);,buf 中会存储"name: zhangsan, age: 18"。
二、文件定位操作:fseek /ftell/rewind
Linux 内核会为每个打开的文件维护文件位置偏移量,读 / 写操作会自动移动该偏移量,默认从文件开头开始。文件定位操作可手动修改偏移量,实现随机读写。
1. 定位偏移量:fseek
int fseek(FILE *stream, long offset, int whence);
- 功能:将文件偏移量定位到从 whence 开始,偏移 offset 字节的位置;
- 参数:
stream:目标文件流;offset:偏移量(可正可负,正为向后偏移,负为向前偏移);whence:参考点(宏定义,核心):SEEK_SET:文件开头(offset 只能为正);SEEK_CUR:当前偏移量位置(offset 可正可负,空文件不能为负);SEEK_END:文件末尾(offset 可正可负);
- 返回值:成功返回 0,失败返回 - 1;
fseek(fp, 0, SEEK_SET); // 定位到文件开头 fseek(fp, 0, SEEK_END); // 定位到文件末尾特殊用法:创建空洞文件(文件中填充
'\0',可提前抢占磁盘空间,如百度云下载的.downloading文件),步骤:fseek定位到指定位置 → 执行一次写操作
2. 获取偏移量:ftell
long ftell(FILE *stream);
- 功能:获取当前文件的位置偏移量;
- 返回值:成功返回偏移量(字节数),失败返回 - 1;
- 常用场景:计算文件大小
fseek(fp, 0, SEEK_END); // 定位到文件末尾 long file_size = ftell(fp); // file_size即为文件总字节数3. 重置到文件开头:rewind
void rewind(FILE *stream); - 功能:将文件偏移量重置到文件开头,无返回值;
- 等价于:
fseek(fp, 0, SEEK_SET);,语法更简洁。
更多推荐



所有评论(0)