一、前置知识:Linux 文件类型与命令行参数
在进行文件操作前,我们需要先了解 Linux 系统中的文件分类,以及如何通过命令行参数灵活传递文件路径等信息。
1.1 Linux 的 7 种文件类型
Linux 是一个 "一切皆文件" 的系统,通过 ll(ls -l 的别名)命令可以查看文件的详细信息,其中第一列的第一个字符代表文件类型,共分为 7 种:
| 类型标识 | 文件类型 | 说明 |
|---|---|---|
| d | 目录文件 | 用于存放文件和子目录,可通过 cd 命令进入 |
| l | 软链接文件 | 类似 Windows 快捷方式,指向源文件或目录 |
| - | 普通文件 | 包含文本、视频、可执行程序等,如 .c 源码、a.out 可执行文件 |
| c | 字符设备文件 | 按字符流传输数据的设备,如键盘、串口,支持顺序访问 |
| b | 块设备文件 | 按块传输数据的存储设备,如硬盘、U 盘,支持随机访问,块大小通常为 512 字节 |
| s | 套接字文件 | 用于进程间网络通信,常见于 /var/run 目录 |
| p | 管道文件 | 用于进程间的本地通信,实现数据的单向传输 |
示例:通过 ll 查看文件类型
# 目录文件(d)
drwxrwxr-x 10 linux linux 4.0K Sep 6 2021 .vimplus/
# 软链接文件(l)
lrwxrwxrwx 1 linux linux 27 Sep 5 2021 .vimrc -> /home/linux/.vimplus/.vimrc
# 普通文件(-)
-rw-rw-r-- 1 linux linux 3.4K Sep 22 11:28 .vimrc.custom.config
# 字符设备文件(c)
crw------- 1 root root 249, 0 Nov 27 17:06 /dev/rtc0
# 块设备文件(b)
brw-rw---- 1 root disk 8, 0 Nov 27 17:06 /dev/sda
1.2 命令行参数:灵活传递程序参数
在 Linux 程序中,通过 main 函数的参数可以接收命令行传入的数据,格式如下:
int main(int argc, char *argv[])
- argc:命令行参数的总个数,包含程序名本身
- argv :字符串数组,存储每个命令行参数,
argv[0]为程序名
示例:打印命令行参数
#include <stdio.h>
int main(int argc, char *argv[])
{
printf("argc is %d\n", argc);
int i = 0;
for (i = 0; i < argc; i++)
{
printf("%d %s\n", i, argv[i]);
}
return 0;
}
编译运行:
gcc main.c -o arg_demo
./arg_demo file1.txt file2.txt
输出结果:
argc is 3
0 ./arg_demo
1 file1.txt
2 file2.txt
命令行参数常用于传递文件路径,让程序可以动态操作不同文件。
二、标准 IO 核心基础:默认流指针与缓存机制
标准 IO 的核心特性体现在「默认流指针」和「缓存机制」上,这是理解 IO 操作行为的关键。
2.1 3 个默认流指针:程序的 "标配输入输出"
程序启动时,系统会自动打开 3 个 FILE* 类型的流指针,覆盖基础输入输出场景,无需手动打开 / 关闭:
| 流指针 | 说明 | 常用函数示例 |
|---|---|---|
stdin |
标准输入(默认键盘) | fgets(buf, sizeof(buf), stdin) |
stdout |
标准输出(默认屏幕) | fputs("hello", stdout) |
stderr |
标准错误输出(默认屏幕) | fprintf(stderr, "错误:文件打开失败\n") |
核心区别 :stdout 是「带缓存」输出,stderr 是「无缓存」输出 ------ 错误信息会直接打印到终端,不会因缓存延迟显示。
示例代码:默认流指针使用
#include <stdio.h>
#include <string.h>
int main() {
char input_buf[1024];
// 1. 从stdin(键盘)读取输入
printf("请输入一句话:"); // printf默认输出到stdout
fgets(input_buf, sizeof(input_buf), stdin); // 读取键盘输入
// 2. 向stdout(屏幕)输出正常信息
fputs("你输入的内容是:", stdout);
fputs(input_buf, stdout);
// 3. 模拟错误,向stderr输出错误信息(无缓存,实时显示)
if (strlen(input_buf) > 50) {
fprintf(stderr, "【错误】输入内容超过50个字符,可能存在风险!\n");
}
return 0;
}
2.2 标准 I/O 的缓存机制:为什么程序 "写了没反应"?
标准 IO 核心是「内存缓存区」:数据先写入内存缓存,满足条件后再批量写入硬件(终端 / 磁盘),以此提升 I/O 效率。缓存分为 3 类,特性如下:
| 缓存类型 | 适用场景 | 缓存大小 | 刷新(写入硬件)条件 |
|---|---|---|---|
| 行缓存 | stdout(终端交互) |
1KB | 1. 遇到换行符 \n;2. 缓存区写满;3. 程序结束;4. 主动调用 fflush(stdout) |
| 全缓存 | 普通文件(如 .txt) | 4KB | 1. 缓存区写满;2. 程序结束;3. 主动调用 fflush(fp)(fp 为文件流指针) |
| 无缓存 | stderr(错误输出) |
0(无) | 数据直接写入硬件,无延迟 |
关键问题:"写了没反应" 的常见场景
#include <stdio.h>
int main() {
// 场景1:stdout行缓存------无换行符,数据暂存缓存,终端无输出
printf("这段文字不会显示"); // 无\n,缓存未刷新
// fflush(stdout); // 取消注释则手动刷新,终端会显示上述文字
// 场景2:文件全缓存------数据暂存缓存,文件中无内容
FILE *fp = fopen("test.txt", "w");
fputs("这段文字暂存缓存", fp); // 缓存未写满,未调用fflush,文件无内容
// fflush(fp); // 取消注释则手动刷新,文件会写入内容
fclose(fp); // 关闭文件时会自动刷新全缓存,注释此行则文件无内容
// 场景3:stderr无缓存------直接输出到终端
fprintf(stderr, "错误信息实时显示\n"); // 无缓存,立即打印
return 0;
}
示例代码:验证缓存机制
#include <stdio.h>
#include <unistd.h> // 用于sleep函数
int main() {
// 1. 验证stdout行缓存:无\n则延迟输出
printf("stdout行缓存测试(无\\n)");
sleep(3); // 休眠3秒,终端此时无输出
fflush(stdout); // 手动刷新,终端显示上述文字
sleep(3); // 再休眠3秒
printf(" ------ 手动fflush后显示\n"); // 带\n,自动刷新
// 2. 验证文件全缓存
FILE *fp = fopen("cache_test.txt", "w");
if (!fp) {
fprintf(stderr, "文件打开失败!\n");
return 1;
}
// 写入少量数据,缓存未写满,文件暂无内容
fputs("全缓存测试:未刷新前文件无内容\n", fp);
printf("此时打开cache_test.txt,文件为空(按回车继续):");
fgetc(stdin); // 等待用户回车
fflush(fp); // 手动刷新全缓存,数据写入文件
printf("再次打开cache_test.txt,已能看到内容\n");
// 3. 验证stderr无缓存
fprintf(stderr, "stderr无缓存:这句话会实时显示,无需等待\n");
sleep(3); // 休眠3秒,验证无延迟
fclose(fp);
return 0;
}
三、标准 IO 文件打开模式:读写操作的前提
使用标准 IO 操作文件的第一步是打开文件,通过 fopen 函数实现。打开模式决定了文件的操作权限,读写操作的行为都由其决定,常见模式如下:
| 模式 | 操作权限 | 注意事项 |
|---|---|---|
| r | 只读 | 目标文件必须存在,写操作会报错 |
| r+ | 读写 | 目标文件必须存在,读写起始位置均为文件开头 |
| w | 只写 | 不存在则创建,存在则清空原有内容,写起始位置为开头 |
| w+ | 读写 | 不存在则创建,存在则清空,读写起始位置均为开头 |
| a | 追加写 | 不存在则创建,写起始位置为文件末尾,不会覆盖原有内容 |
| a+ | 追加读写 | 不存在则创建,写在末尾,读在开头,读新写入内容需调整文件指针 |
核心函数:fopen
FILE *fopen(const char *pathname, const char *mode);
- pathname:文件的路径(绝对路径或相对路径)+ 文件名
- mode:文件打开模式
- 返回值 :成功返回
FILE*类型的文件流指针(包含文件属性、读写位置等信息);失败返回NULL
注意 :文件打开后必须通过 fclose 函数关闭,释放系统资源。
四、标准 IO 文件写操作:三种核心方法
标准 IO 提供了多种文件写操作函数,适用于不同场景:单字符写入、字符串写入、二进制数据写入。本文结合代码实例讲解这三种写入方法,覆盖文本文件和二进制文件的写操作场景。
4.1 单字符写入:fputc
fputc 函数用于向文件写入单个字符,适用于逐字符处理的场景(如文本编辑器逐字保存)。
函数原型
int fputc(int c, FILE *stream);
- c:要写入的字符(实际是 ASCII 码值)
- stream :文件流指针(
fopen的返回值) - 返回值 :成功返回写入的字符;失败返回
EOF(EOF是宏定义,值为 -1)
代码实例:逐字符写入文件
需求:通过命令行传递文件路径,向文件写入字符串 "Hello Linux File Write"。
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
// 检查命令行参数:必须传入文件路径
if (argc != 2)
{
printf("Usage: %s <filename>\n", argv[0]);
return -1;
}
// 1. 打开文件:追加写模式(a),避免覆盖原有内容
FILE *fp = fopen(argv[1], "a");
if (fp == NULL)
{
perror("fopen error"); // 打印错误信息
return -1;
}
// 2. 准备写入的字符串
char *str = "Hello Linux File Write\n";
int len = strlen(str);
// 3. 逐字符写入文件
for (int i = 0; i < len; i++)
{
if (fputc(str[i], fp) == EOF)
{
perror("fputc error");
fclose(fp); // 失败时也要关闭文件
return -1;
}
}
printf("Write success by fputc\n");
// 4. 关闭文件
fclose(fp);
return 0;
}
编译运行:
gcc fputc_demo.c -o fputc_demo
./fputc_demo test.txt
cat test.txt
输出结果:
Hello Linux File Write
4.2 字符串写入:fputs
fputc 逐字符写入效率较低,fputs 函数支持一次性写入一个字符串,是文本文件写入的常用方法。
函数原型
int fputs(const char *s, FILE *stream);
- s :要写入的字符串(以
\0结尾) - stream:文件流指针
- 返回值 :成功返回非负整数;失败返回
EOF
代码实例:字符串写入文件
需求 :向文件写入多行文本,对比 fputc 提升写入效率。
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <filename>\n", argv[0]);
return -1;
}
// 1. 打开文件:只写模式(w),新建或清空文件
FILE *fp = fopen(argv[1], "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
// 2. 多行字符串写入
char *lines[] = {
"Linux Standard IO\n",
"File Write by fputs\n",
"C Language System Programming\n"
};
int line_num = sizeof(lines) / sizeof(lines[0]);
for (int i = 0; i < line_num; i++)
{
if (fputs(lines[i], fp) == EOF)
{
perror("fputs error");
fclose(fp);
return -1;
}
}
printf("Write success by fputs\n");
// 3. 关闭文件
fclose(fp);
return 0;
}
编译运行:
gcc fputs_demo.c -o fputs_demo
./fputs_demo test.txt
cat test.txt
输出结果:
Linux Standard IO
File Write by fputs
C Language System Programming
4.3 二进制写入:fwrite
除了文本文件,标准 IO 还支持二进制文件写入(如图片、视频、可执行程序、结构体数据),核心函数为 fwrite,可实现二进制数据的原生存储,避免文本转换导致的数据丢失。
函数原型
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- ptr:待写入数据的缓冲区地址(如结构体变量、数组的地址)
- size:单个数据块的大小(单位:字节)
- nmemb:数据块的个数
- stream:文件流指针
- 返回值 :成功写入的数据块个数(若返回值 <
nmemb,说明写入失败或部分失败)
代码实例:结构体数据二进制写入文件
需求 :定义 "学生信息" 结构体,通过 fwrite 将多个学生的二进制数据写入文件,保证数据的原生存储(可通过 fread 无损读取)。
#include <stdio.h>
#include <string.h>
// 定义学生信息结构体
typedef struct {
char name[20]; // 姓名
int age; // 年龄
float score; // 成绩
} Student;
int main(int argc, char *argv[])
{
// 检查命令行参数:必须传入二进制文件路径
if (argc != 2)
{
printf("Usage: %s <binary_file>\n", argv[0]);
return -1;
}
// 1. 打开文件:二进制只写模式(wb)
// 注:Linux下文本/二进制模式无差异,但跨平台(如Windows)需显式加b
FILE *fp = fopen(argv[1], "wb");
if (fp == NULL)
{
perror("fopen error"); // 打印错误原因(如权限不足、路径不存在)
return -1;
}
// 2. 准备待写入的结构体数据
Student students[] = {
{"Zhang San", 18, 92.5},
{"Li Si", 19, 88.0},
{"Wang Wu", 17, 95.0}
};
int stu_num = sizeof(students) / sizeof(students[0]);
// 3. 二进制写入结构体数组
size_t write_num = fwrite(students, sizeof(Student), stu_num, fp);
if (write_num != stu_num)
{
perror("fwrite error");
fclose(fp);
return -1;
}
printf("Write %zu students data success by fwrite\n", write_num);
// 4. 关闭文件
fclose(fp);
return 0;
}
编译运行:
gcc fwrite_demo.c -o fwrite_demo
./fwrite_demo student.dat
# 查看二进制文件(可通过hexdump辅助查看)
hexdump -C student.dat
输出结果(核心片段):
Write 3 students data success by fwrite
00000000 5a 68 61 6e 67 20 53 61 6e 00 00 00 00 00 00 00 |Zhang San.......|
00000010 00 00 00 00 12 00 00 00 00 00 50 41 4c 69 20 53 |.........PALI S|
00000020 69 00 00 00 00 00 00 00 00 00 00 00 13 00 00 00 |i...............|
00000030 00 00 00 41 57 61 6e 67 20 57 75 00 00 00 00 00 |...AWang Wu.....|
00000040 00 00 00 00 00 11 00 00 00 00 00 c0 41 |.............A|
五、标准 IO 文件读操作:三种核心方法
与写操作对应,标准 IO 同样提供了单字符读取、字符串读取、二进制读取三种核心方法,分别对应 fgetc、fgets、fread 函数,覆盖不同的读取场景。
5.1 单字符读取:fgetc
fgetc 函数用于从文件中读取单个字符,适用于逐字符解析的场景(如文本解析器)。
函数原型
int fgetc(FILE *stream);
- stream:文件流指针
- 返回值 :成功返回读取的字符(ASCII 码值);读到文件末尾或失败返回
EOF
代码实例:逐字符读取文件
需求 :读取 test.txt 文件内容,逐字符输出到终端。
#include <stdio.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <filename>\n", argv[0]);
return -1;
}
// 1. 打开文件:只读模式(r)
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
// 2. 逐字符读取文件
int ch;
printf("File content:\n");
while ((ch = fgetc(fp)) != EOF)
{
putchar(ch); // 输出到终端
}
// 3. 检查读取是否正常结束
if (ferror(fp))
{
perror("fgetc error");
fclose(fp);
return -1;
}
// 4. 关闭文件
fclose(fp);
return 0;
}
编译运行:
gcc fgetc_demo.c -o fgetc_demo
./fgetc_demo test.txt
输出结果:
File content:
Linux Standard IO
File Write by fputs
C Language System Programming
5.2 字符串读取:fgets
fgetc 逐字符读取效率较低,fgets 函数支持一次性读取一行字符串,是文本文件读取的常用方法,可自动处理换行符。
函数原型
char *fgets(char *s, int size, FILE *stream);
- s:存储读取字符串的缓冲区
- size :缓冲区大小(读取字符数不超过
size-1,预留\0位置) - stream:文件流指针
- 返回值 :成功返回缓冲区地址
s;读到文件末尾或失败返回NULL
代码实例:按行读取文件
需求 :读取 test.txt 文件,逐行输出并统计行数。
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <filename>\n", argv[0]);
return -1;
}
FILE *fp = fopen(argv[1], "r");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char buf[1024]; // 定义缓冲区
int line_count = 0;
printf("File content by line:\n");
// 逐行读取文件,直到末尾
while (fgets(buf, sizeof(buf), fp) != NULL)
{
line_count++;
// 去除fgets读取的换行符(可选)
buf[strcspn(buf, "\n")] = '\0';
printf("Line %d: %s\n", line_count, buf);
}
if (ferror(fp))
{
perror("fgets error");
fclose(fp);
return -1;
}
printf("Total lines: %d\n", line_count);
fclose(fp);
return 0;
}
编译运行:
gcc fgets_demo.c -o fgets_demo
./fgets_demo test.txt
输出结果:
File content by line:
Line 1: Linux Standard IO
Line 2: File Write by fputs
Line 3: C Language System Programming
Total lines: 3
5.3 二进制读取:fread
fread 函数用于读取二进制文件数据,可无损读取通过 fwrite 写入的结构体、多媒体等二进制数据,是二进制文件操作的核心函数。
函数原型
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- ptr:存储读取数据的缓冲区地址
- size:单个数据块的大小(单位:字节)
- nmemb:期望读取的数据块个数
- stream:文件流指针
- 返回值 :成功读取的数据块个数;若返回值小于
nmemb,可能是读到文件末尾或出错
代码实例:读取二进制结构体文件
需求 :读取 student.dat 文件中的学生信息,输出到终端。
#include <stdio.h>
#include <string.h>
// 与写入时一致的结构体定义
typedef struct {
char name[20];
int age;
float score;
} Student;
int main(int argc, char *argv[])
{
if (argc != 2)
{
printf("Usage: %s <binary_file>\n", argv[0]);
return -1;
}
// 1. 打开文件:二进制只读模式(rb)
FILE *fp = fopen(argv[1], "rb");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
Student stu;
size_t read_num;
int count = 0;
printf("Student info:\n");
printf("Name\t\tAge\tScore\n");
printf("---------------------------\n");
// 2. 循环读取结构体数据,直到文件末尾
while ((read_num = fread(&stu, sizeof(Student), 1, fp)) == 1)
{
count++;
printf("%s\t\t%d\t%.1f\n", stu.name, stu.age, stu.score);
}
// 3. 检查读取状态
if (ferror(fp))
{
perror("fread error");
fclose(fp);
return -1;
}
printf("---------------------------\n");
printf("Total read %d students\n", count);
// 4. 关闭文件
fclose(fp);
return 0;
}
编译运行:
gcc fread_demo.c -o fread_demo
./fread_demo student.dat
输出结果:
Student info:
Name Age Score
---------------------------
Zhang San 18 92.5
Li Si 19 88.0
Wang Wu 17 95.0
---------------------------
Total read 3 students
六、文件定位:让指针 "跳着走"
文件流的「读写指针」(类似光标)决定了下一次读写的位置,标准 I/O 提供 3 个函数控制指针位置:
| 函数 | 功能 | 函数原型 | 核心参数 / 返回值 |
|---|---|---|---|
fseek |
移动读写指针 | int fseek(FILE *stream, long offset, int whence); |
offset:偏移字节(正→后移,负→前移);whence:起始位置(SEEK_SET/SEEK_CUR/SEEK_END);返回 0 = 成功,-1 = 失败 |
ftell |
获取当前指针位置 | long ftell(FILE *stream); |
返回:从文件开头到当前指针的字节数;失败返回 - 1 |
rewind |
指针复位到文件开头 | void rewind(FILE *stream); |
等价于 fseek(stream, 0, SEEK_SET),无返回值 |
核心常量说明:
SEEK_SET:文件开头(偏移量必须非负);SEEK_CUR:当前指针位置(偏移量可正可负);SEEK_END:文件末尾(偏移量通常为负,向前偏移)。
示例代码:文件定位实战
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp = fopen("position_test.txt", "w+"); // w+:读写模式,创建/清空文件
if (!fp) {
fprintf(stderr, "文件打开失败!\n");
return 1;
}
// 1. 写入初始内容
const char *content = "Hello, File Position!";
fputs(content, fp);
printf("写入的内容:%s\n", content);
// 2. rewind:指针回到文件开头
rewind(fp);
printf("rewind后,指针位置:%ld\n", ftell(fp)); // 输出0(文件开头)
// 3. fseek:移动指针到第6个字节(跳过"Hello,")
fseek(fp, 6, SEEK_SET); // 从开头偏移6字节(索引从0开始)
printf("fseek后,指针位置:%ld\n", ftell(fp)); // 输出6
// 4. 读取指针位置后的内容
char read_buf[1024];
fgets(read_buf, sizeof(read_buf), fp);
printf("从第6字节开始读取:%s\n", read_buf); // 输出" File Position!"
// 5. fseek:从末尾向前偏移5字节
fseek(fp, -5, SEEK_END);
printf("文件末尾向前偏移5字节,指针位置:%ld\n", ftell(fp)); // 输出总长度-5
fgets(read_buf, sizeof(read_buf), fp);
printf("从该位置读取:%s\n", read_buf); // 输出"tion!"
// 6. fseek:从当前位置向后偏移3字节
fseek(fp, 3, SEEK_CUR);
printf("当前位置向后偏移3字节,指针位置:%ld\n", ftell(fp));
// 此时指针超出文件末尾,写入会追加内容
fputs(" [追加内容]", fp);
// 7. 验证追加结果:指针回到开头,读取全部内容
rewind(fp);
fgets(read_buf, sizeof(read_buf), fp);
printf("最终文件内容:%s\n", read_buf);
fclose(fp);
return 0;
}
七、文件操作的完整流程与注意事项
7.1 标准 IO 文件操作三步曲
- 打开文件 :调用
fopen,指定正确的路径和模式,必须检查返回值是否为NULL,避免空指针操作。 - 读写操作 :根据需求选择
fputc/fputs/fwrite或fgetc/fgets/fread,严格处理函数返回值,判断操作是否成功。 - 关闭文件 :调用
fclose释放资源,即使操作失败也要关闭文件,防止资源泄漏。
7.2 关键注意事项
-
模式选择
- 避免滥用
w模式:w会清空文件原有内容,如需追加内容请使用a或a+。 a+模式的读写位置:写在末尾,读在开头,如需读取刚写入的内容,需通过fseek函数调整文件指针。- 二进制读写需用
rb/wb/ab模式:跨平台场景下,避免文本模式的换行符转换(如 Windows 下\n会转为\r\n)。
- 避免滥用
-
错误处理
- 使用
perror打印错误信息,perror会自动关联errno变量,输出具体错误原因(如文件不存在、权限不足)。 - 读取操作结束后,可通过
ferror判断是正常读到文件末尾,还是发生错误。
- 使用
-
缓冲区刷新
- 标准 IO 默认使用缓冲机制,数据会先存入缓冲区,满足条件后才写入磁盘。
- 可通过
fflush(fp)手动刷新缓冲区,确保数据立即写入;关闭文件时fclose会自动刷新缓冲区。
八、man 手册:Linux 编程的 "百科全书"
在 Linux 系统编程中,man 手册是查询函数用法的最佳工具,通过指定手册章节可以精准定位信息:
man 1 xxx:查询命令的用法(如man 1 ls)man 2 xxx:查询系统调用函数的用法(如man 2 open)man 3 xxx:查询标准库函数的用法(如man 3 fputc)
示例 :查询 fwrite 函数的详细说明
man 3 fwrite
导出 man 手册内容:
man 3 fwrite > fwrite_manual.txt # 将fwrite的帮助信息保存到文件
九、总结
本文从 Linux 文件类型和命令行参数入手,系统讲解了标准 IO 的核心特性与操作方法,核心逻辑可总结为 "3+3+3" 体系:
| 核心维度 | 关键能力 |
|---|---|
| 3 个默认流指针 | stdin/stdout/stderr 覆盖基础输入输出,stderr 无缓存保证错误实时显示 |
| 3 种缓存机制 | 行缓存(stdout)、全缓存(文件)、无缓存(stderr),平衡效率与实时性 |
| 3 类读写方法 | 字符 / 字符串 / 二进制读写(fputc/fputs/fwrite/fgetc/fgets/fread),适配不同场景 |
| 3 个定位函数 | fseek(移动指针)、ftell(获取位置)、rewind(复位开头),灵活控制读写位置 |
| 操作类型 | 函数 | 适用场景 | 特点 |
|---|---|---|---|
| 写操作 | fputc | 逐字符处理文本文件 | 精细化控制,效率较低 |
| 写操作 | fputs | 批量写入字符串文本 | 效率高,文本文件首选 |
| 写操作 | fwrite | 二进制数据(结构体、多媒体)写入 | 原生存储,无数据丢失 |
| 读操作 | fgetc | 逐字符解析文本文件 | 精细化解析,效率较低 |
| 读操作 | fgets | 按行读取文本文件 | 效率高,文本文件首选 |
| 读操作 | fread | 二进制数据(结构体、多媒体)读取 | 无损读取,二进制文件首选 |
| 定位操作 | fseek | 灵活调整读写指针位置 | 支持多起始位置偏移 |
| 定位操作 | ftell | 获取当前指针位置 | 便于记录和校验读写位置 |
| 定位操作 | rewind | 快速将指针复位到文件开头 | 无返回值,使用简单 |