以下是C标准库中常用文件I/O函数,定义在头文件 <stdio.h>
中,适用于文本和二进制文件的读写。它们是 ANSI C 标准的一部分,在大多数操作系统(如 Windows、Linux、macOS)下都支持。
1. fopen
FILE *fopen(const char *filename, const char *mode);
- 参数:
filename
:要打开的文件名(路径)。mode
:打开模式,例如"r"
(读)、"w"
(写)、"a"
(追加)、"rb"
(二进制读)等。
- 返回值:
- 成功时返回指向
FILE
的指针; - 失败返回
NULL
。
- 成功时返回指向
2. fclose
int fclose(FILE *stream);
- 参数:
stream
:之前通过fopen()
打开的文件指针。
- 返回值:
- 成功返回
0
; - 出错返回
EOF
(通常是-1
)。
- 成功返回
3. fread
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
- 参数:
ptr
:指向存储读取数据的缓冲区。size
:每个元素的大小(字节数)。nmemb
:要读取的元素个数。stream
:文件指针。
- 返回值:
- 成功读取的完整元素数量(小于等于
nmemb
); - 若发生错误或到达文件末尾可能返回更少。
- 成功读取的完整元素数量(小于等于
4. fwrite
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
- 参数:
ptr
:指向要写入的数据的指针。size
:每个元素的大小。nmemb
:要写入的元素个数。stream
:文件指针。
- 返回值:
- 成功写入的完整元素数量;
- 如果小于
nmemb
,可能发生了错误。
5. fgetc
int fgetc(FILE *stream);
- 参数:
stream
:文件指针。
- 返回值:
- 成功返回读取到的字符(转换为
unsigned char
后转成int
); - 出错或文件结束返回
EOF
。
- 成功返回读取到的字符(转换为
6. fgets
char *fgets(char *s, int n, FILE *stream);
- 参数:
s
:用于存储读取内容的字符串。n
:最多读取n - 1
个字符(留一个给\0
)。stream
:文件指针。
- 返回值:
- 成功返回
s
; - 文件结束或出错返回
NULL
。
- 成功返回
7. fputc
int fputc(int c, FILE *stream);
- 参数:
c
:要写入的字符(转换为unsigned char
后作为int
传递)。stream
:文件指针。
- 返回值:
- 成功返回写入的字符;
- 出错返回
EOF
。
8. fputs
int fputs(const char *s, FILE *stream);
- 参数:
s
:要写入的字符串(不包括结尾的\0
)。stream
:文件指针。
- 返回值:
- 成功返回非负整数;
- 出错返回
EOF
。
9. fprintf
int fprintf(FILE *stream, const char *format, ...);
- 参数:
stream
:文件指针。format
:格式化字符串。- 可变参数列表,对应
format
中的格式符。
- 返回值:
- 成功返回写入的字符数;
- 出错返回负值。
10. fscanf
int fscanf(FILE *stream, const char *format, ...);
- 参数:
stream
:文件指针。format
:格式化字符串。- 可变参数列表,用于接收读取的数据。
- 返回值:
- 成功匹配并赋值的输入项数量;
- 出错或文件结束返回
EOF
。
11. feof
int feof(FILE *stream);
- 参数:
stream
:文件指针。
- 返回值:
- 如果已到达文件末尾,返回非零值;
- 否则返回 0。
12. ferror
int ferror(FILE *stream);
- 参数:
stream
:文件指针。
- 返回值:
- 如果流上发生错误,返回非零值;
- 否则返回 0。
13. rewind
void rewind(FILE *stream);
- 参数:
stream
:文件指针。
- 返回值:
- 无返回值。将文件指针移动到文件开头,并清除错误标志。
14. ftell
long ftell(FILE *stream);
- 参数:
stream
:文件指针。
- 返回值:
- 返回当前文件指针的位置(从文件开始处算起的字节数);
- 出错返回
-1L
。
15. fseek
int fseek(FILE *stream, long offset, int whence);
- 参数:
stream
:文件指针。offset
:偏移量(字节数)。whence
:起点位置,如SEEK_SET
(文件开头)、SEEK_CUR
(当前位置)、SEEK_END
(文件末尾)。
- 返回值:
- 成功返回
0
; - 出错返回非零值。
- 成功返回
✅ 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义一个简单的结构体
typedef struct {
int id;
char name[32];
float salary;
} Employee;
int main() {
FILE *bin_file = fopen("employees.dat", "wb+");
FILE *txt_file = fopen("data.txt", "w+");
if (!bin_file || !txt_file) {
perror("文件打开失败");
return EXIT_FAILURE;
}
// ========== fwrite + fread 示例 ==========
Employee emp1 = {101, "Alice", 8000.0f};
Employee emp2 = {0};
// 写入结构体到二进制文件
fwrite(&emp1, sizeof(Employee), 1, bin_file);
rewind(bin_file); // 回到文件开头
// 读取结构体
fread(&emp2, sizeof(Employee), 1, bin_file);
printf("从二进制文件读取的数据:\n");
printf("ID: %d, Name: %s, Salary: %.2f\n", emp2.id, emp2.name, emp2.salary);
// 检查是否有错误
if (ferror(bin_file)) {
printf("二进制文件读写出错。\n");
clearerr(bin_file); // 清除错误标志
}
// ========== fprintf + fscanf 示例 ==========
// 写入格式化文本数据
fprintf(txt_file, "%d %s %.2f\n", emp1.id, emp1.name, emp1.salary);
rewind(txt_file); // 回到文件开头
// 读取格式化文本数据
Employee emp3 = {0};
fscanf(txt_file, "%d %s %f", &emp3.id, emp3.name, &emp3.salary);
printf("\n从文本文件读取的数据:\n");
printf("ID: %d, Name: %s, Salary: %.2f\n", emp3.id, emp3.name, emp3.salary);
if (ferror(txt_file)) {
printf("文本文件读写出错。\n");
}
// 关闭文件
fclose(bin_file);
fclose(txt_file);
return 0;
}
🔍 输出结果(示例)
从二进制文件读取的数据:
ID: 101, Name: Alice, Salary: 8000.00
从文本文件读取的数据:
ID: 101, Name: Alice, Salary: 8000.00