目录
🌷前言:
在前一篇内容中,我们学习了 C 语言的递归函数,包括递归的基本概念、工作原理和实现方法,以及递归在数学问题、数据结构遍历、分治算法等领域的应用。递归通过函数调用自身,能够将复杂问题分解为更小的同类问题,以简洁优雅的方式解决许多难题。
今天,我们将学习 C 语言的文件操作。在之前的学习中,我们的数据都是存储在内存中的,程序结束后数据就会丢失。文件操作允许我们将数据存储在外部存储设备(如硬盘)上,实现数据的持久化保存和读取。文件操作是程序与外部世界交互的重要方式,广泛应用于数据存储、配置管理、日志记录等场景。掌握文件操作是编写实用程序的必备技能。
一、文件操作的基本概念
1.1 什么是文件?
在计算机中,文件是存储在外部存储设备上的一组相关数据的集合。文件具有以下特点:
- 文件有一个唯一的文件名,用于标识和访问文件
- 文件中的数据以字节序列的形式存储
- 文件可以长期保存,不受程序运行状态的影响
- 文件可以被多个程序共享访问
在 C 语言中,文件被视为字节流,无论是文本还是二进制数据,都以字节为单位进行处理。
1.2 文件的类型
根据存储格式,文件可以分为两类:
-
文本文件(Text File):
- 以字符编码(如 ASCII、UTF-8)的形式存储数据
- 内容可以被文本编辑器直接阅读
- 换行符在不同操作系统中可能不同(Windows: \r\n, Linux: \n, macOS: \n)
- 适合存储人类可读的数据,如配置文件、日志等
-
二进制文件(Binary File):
- 以数据在内存中的原始形式存储
- 内容通常不能被文本编辑器直接阅读
- 数据存储紧凑,没有格式转换开销
- 适合存储程序内部数据结构,如图片、音频、序列化对象等
1.3 文件操作的基本流程
C 语言中,文件操作通常遵循以下基本流程:
- 打开文件:建立程序与文件的连接,准备进行读写操作
- 读写文件:按照需要读取或写入数据
- 关闭文件:断开程序与文件的连接,释放相关资源
二、文件指针
在 C 语言中,文件操作通过文件指针(File Pointer)来进行。文件指针是指向FILE
结构体的指针,FILE
结构体定义在<stdio.h>
头文件中,包含了文件的相关信息(如文件名、文件状态、当前位置等)。
2.1 文件指针的声明
文件指针的声明格式:
c
运行
FILE *指针名;
例如:
c
运行
FILE *fp; // 声明一个文件指针fp
2.2 标准流
C 语言预定义了三个标准文件指针,无需打开即可直接使用:
- 标准输入(stdin):通常关联到键盘,用于输入操作
- 标准输出(stdout):通常关联到屏幕,用于输出操作
- 标准错误(stderr):通常关联到屏幕,用于错误信息输出
这些标准流定义在<stdio.h>
中,我们常用的printf
、scanf
函数就是通过stdout
和stdin
进行操作的。
三、文件的打开与关闭
3.1 打开文件:fopen 函数
fopen
函数用于打开一个文件,并返回一个文件指针。
函数原型:
c
运行
FILE *fopen(const char *filename, const char *mode);
- 参数
filename
:要打开的文件名(可以包含路径) - 参数
mode
:打开文件的模式(访问方式) - 返回值:成功时返回文件指针;失败时返回
NULL
常用的文件打开模式:
模式 | 含义 | 对文本文件的影响 | 对二进制文件的影响 |
---|---|---|---|
"r" | 只读方式打开 | 从文件开头读取 | 从文件开头读取 |
"w" | 只写方式打开 | 若文件存在则清空内容,若不存在则创建 | 同左 |
"a" | 追加方式打开 | 若文件存在则在末尾追加,若不存在则创建 | 同左 |
"r+" | 读写方式打开 | 从文件开头读写 | 从文件开头读写 |
"w+" | 读写方式打开 | 若文件存在则清空内容,若不存在则创建 | 同左 |
"a+" | 读写方式打开 | 可读取整个文件,但写入只能追加到末尾 | 同左 |
对于二进制文件,需要在模式字符串后添加 "b":
- "rb":只读打开二进制文件
- "wb":只写打开二进制文件
- "ab":追加打开二进制文件
- "rb+"、"wb+"、"ab+":对应的读写模式
注意:
- 打开文件时应始终检查返回的文件指针是否为
NULL
,以处理文件打开失败的情况 - 不同操作系统对文件路径的表示可能不同(Windows 使用反斜杠
\
,Linux 和 macOS 使用正斜杠/
)
3.2 关闭文件:fclose 函数
fclose
函数用于关闭一个已打开的文件,释放相关资源。
函数原型:
c
运行
int fclose(FILE *stream);
- 参数
stream
:要关闭的文件指针 - 返回值:成功时返回 0;失败时返回 EOF(-1)
注意:
- 使用完文件后应及时关闭,避免资源泄露
- 关闭文件后,文件指针不再有效,不应再使用
示例:文件的打开与关闭
c
运行
#include <stdio.h>
int main() {
FILE *fp;
// 打开文件
fp = fopen("example.txt", "w");
// 检查文件是否成功打开
if (fp == NULL) {
printf("无法打开文件!\n");
return 1; // 非正常退出
}
printf("文件打开成功!\n");
// 关闭文件
if (fclose(fp) == 0) {
printf("文件关闭成功!\n");
} else {
printf("文件关闭失败!\n");
}
return 0;
}
四、文本文件的读写操作
文本文件的读写操作以字符或字符串为单位,C 语言提供了一系列函数用于文本文件的读写。
4.1 字符读写
4.1.1 读取字符:fgetc 函数
fgetc
函数从文件中读取一个字符。
函数原型:
c
运行
int fgetc(FILE *stream);
- 参数
stream
:文件指针 - 返回值:成功时返回读取的字符(转换为 int);失败或到达文件末尾时返回 EOF
4.1.2 写入字符:fputc 函数
fputc
函数向文件中写入一个字符。
函数原型:
c
运行
int fputc(int character, FILE *stream);
- 参数
character
:要写入的字符(int 类型,通常传递 char 值) - 参数
stream
:文件指针 - 返回值:成功时返回写入的字符;失败时返回 EOF
示例:使用 fputc 和 fgetc 读写字符
c
运行
#include <stdio.h>
int main() {
FILE *fp;
char ch;
// 写入字符到文件
fp = fopen("chars.txt", "w");
if (fp == NULL) {
printf("无法打开文件进行写入!\n");
return 1;
}
// 写入A到Z的大写字母
for (ch = 'A'; ch <= 'Z'; ch++) {
fputc(ch, fp);
}
fclose(fp);
printf("字符写入完成!\n");
// 从文件读取字符
fp = fopen("chars.txt", "r");
if (fp == NULL) {
printf("无法打开文件进行读取!\n");
return 1;
}
printf("文件内容:");
// 读取并打印所有字符,直到文件末尾
while ((ch = fgetc(fp)) != EOF) {
printf("%c", ch);
}
printf("\n");
fclose(fp);
return 0;
}
输出结果:
plaintext
字符写入完成!
文件内容:ABCDEFGHIJKLMNOPQRSTUVWXYZ
4.2 字符串读写
4.2.1 读取字符串:fgets 函数
fgets
函数从文件中读取一个字符串。
函数原型:
c
运行
char *fgets(char *str, int n, FILE *stream);
- 参数
str
:存储读取字符串的缓冲区 - 参数
n
:最多读取 n-1 个字符(留出一个位置给终止符 '\0') - 参数
stream
:文件指针 - 返回值:成功时返回 str;失败或到达文件末尾时返回 NULL
注意:fgets
会读取换行符 '\n' 并将其包含在字符串中,遇到换行符或文件末尾会停止读取。
4.2.2 写入字符串:fputs 函数
fputs
函数向文件中写入一个字符串。
函数原型:
c
运行
int fputs(const char *str, FILE *stream);
- 参数
str
:要写入的字符串 - 参数
stream
:文件指针 - 返回值:成功时返回非负值;失败时返回 EOF
注意:fputs
不会自动添加换行符,需要显式写入 '\n'。
示例:使用 fputs 和 fgets 读写字符串
c
运行
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp;
char buffer[100];
// 写入字符串到文件
fp = fopen("strings.txt", "w");
if (fp == NULL) {
printf("无法打开文件进行写入!\n");
return 1;
}
fputs("Hello, World!\n", fp);
fputs("这是一个字符串写入示例。\n", fp);
fputs("C语言文件操作很有趣!", fp);
fclose(fp);
printf("字符串写入完成!\n");
// 从文件读取字符串
fp = fopen("strings.txt", "r");
if (fp == NULL) {
printf("无法打开文件进行读取!\n");
return 1;
}
printf("文件内容:\n");
// 读取并打印所有行,直到文件末尾
while (fgets(buffer, sizeof(buffer), fp) != NULL) {
printf("%s", buffer);
}
fclose(fp);
return 0;
}
输出结果:
plaintext
字符串写入完成!
文件内容:
Hello, World!
这是一个字符串写入示例。
C语言文件操作很有趣!
4.3 格式化读写
4.3.1 格式化读取:fscanf 函数
fscanf
函数从文件中按指定格式读取数据,类似于scanf
,但从文件读取而不是标准输入。
函数原型:
c
运行
int fscanf(FILE *stream, const char *format, ...);
- 参数
stream
:文件指针 - 参数
format
:格式控制字符串 - 参数
...
:存储读取结果的变量地址列表 - 返回值:成功读取的数据项数;失败或到达文件末尾时返回 EOF
4.3.2 格式化写入:fprintf 函数
fprintf
函数按指定格式向文件中写入数据,类似于printf
,但写入到文件而不是标准输出。
函数原型:
c
运行
int fprintf(FILE *stream, const char *format, ...);
- 参数
stream
:文件指针 - 参数
format
:格式控制字符串 - 参数
...
:要写入的数据 - 返回值:成功写入的字符数;失败时返回负数
示例:使用 fprintf 和 fscanf 进行格式化读写
c
运行
#include <stdio.h>
// 学生结构体
typedef struct {
int id;
char name[20];
float score;
} Student;
int main() {
FILE *fp;
Student students[3] = {
{101, "张三", 90.5},
{102, "李四", 85.0},
{103, "王五", 92.5}
};
Student s;
// 格式化写入学生信息
fp = fopen("students.txt", "w");
if (fp == NULL) {
printf("无法打开文件进行写入!\n");
return 1;
}
for (int i = 0; i < 3; i++) {
fprintf(fp, "%d %s %.1f\n",
students[i].id,
students[i].name,
students[i].score);
}
fclose(fp);
printf("学生信息写入完成!\n");
// 格式化读取学生信息
fp = fopen("students.txt", "r");
if (fp == NULL) {
printf("无法打开文件进行读取!\n");
return 1;
}
printf("读取的学生信息:\n");
printf("ID\t姓名\t成绩\n");
printf("------------------------\n");
while (fscanf(fp, "%d %s %f", &s.id, s.name, &s.score) == 3) {
printf("%d\t%s\t%.1f\n", s.id, s.name, s.score);
}
fclose(fp);
return 0;
}
输出结果:
plaintext
学生信息写入完成!
读取的学生信息:
ID 姓名 成绩
------------------------
101 张三 90.5
102 李四 85.0
103 王五 92.5
五、二进制文件的读写操作
二进制文件的读写操作以字节为单位,可以直接读写内存中的数据结构,使用fread
和fwrite
函数。
5.1 读取二进制数据:fread 函数
fread
函数从二进制文件中读取数据。
函数原型:
c
运行
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
- 参数
ptr
:存储读取数据的缓冲区指针 - 参数
size
:每个数据项的大小(以字节为单位) - 参数
count
:要读取的数据项数量 - 参数
stream
:文件指针 - 返回值:成功读取的数据项数量(可能小于 count,甚至为 0)
5.2 写入二进制数据:fwrite 函数
fwrite
函数向二进制文件中写入数据。
函数原型:
c
运行
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
- 参数
ptr
:指向要写入数据的指针 - 参数
size
:每个数据项的大小(以字节为单位) - 参数
count
:要写入的数据项数量 - 参数
stream
:文件指针 - 返回值:成功写入的数据项数量(若小于 count 则表示出错)
示例:使用 fread 和 fwrite 读写二进制文件
c
运行
#include <stdio.h>
#include <string.h>
// 产品结构体
typedef struct {
int id;
char name[50];
float price;
int quantity;
} Product;
int main() {
FILE *fp;
Product products[3] = {
{1001, "笔记本电脑", 5999.99f, 10},
{1002, "智能手机", 3999.99f, 20},
{1003, "平板电脑", 2499.99f, 15}
};
Product p;
// 写入二进制数据
fp = fopen("products.dat", "wb");
if (fp == NULL) {
printf("无法打开文件进行写入!\n");
return 1;
}
// 写入整个产品数组
size_t written = fwrite(products, sizeof(Product), 3, fp);
printf("成功写入 %zu 个产品记录\n", written);
fclose(fp);
// 读取二进制数据
fp = fopen("products.dat", "rb");
if (fp == NULL) {
printf("无法打开文件进行读取!\n");
return 1;
}
printf("\n读取的产品信息:\n");
printf("ID\t名称\t\t价格\t数量\n");
printf("----------------------------------------\n");
// 逐个读取产品记录
while (fread(&p, sizeof(Product), 1, fp) == 1) {
printf("%d\t%s\t%.2f\t%d\n",
p.id, p.name, p.price, p.quantity);
}
fclose(fp);
return 0;
}
输出结果:
plaintext
成功写入 3 个产品记录
读取的产品信息:
ID 名称 价格 数量
----------------------------------------
1001 笔记本电脑 5999.99 10
1002 智能手机 3999.99 20
1003 平板电脑 2499.99 15
文本文件与二进制文件的比较:
- 文本文件存储的是字符的编码,人可以直接阅读;二进制文件存储的是数据的原始字节,通常需要专用程序解析
- 文本文件读写需要进行格式转换,效率较低;二进制文件直接读写内存数据,效率较高
- 文本文件便于调试和移植;二进制文件更节省空间,适合存储复杂数据结构
六、文件定位操作
文件定位操作允许我们移动文件内部的读写指针,实现随机访问文件的不同位置。
6.1 获取当前位置:ftell 函数
ftell
函数返回文件当前的读写位置。
函数原型:
c
运行
long int ftell(FILE *stream);
- 参数
stream
:文件指针 - 返回值:成功时返回当前位置(相对于文件开头的字节数);失败时返回 - 1L
6.2 设置文件位置:fseek 函数
fseek
函数设置文件的读写位置。
函数原型:
c
运行
int fseek(FILE *stream, long int offset, int whence);
- 参数
stream
:文件指针 - 参数
offset
:偏移量(字节数) - 参数
whence
:起始位置,取值可以是:- SEEK_SET:从文件开头开始
- SEEK_CUR:从当前位置开始
- SEEK_END:从文件末尾开始
- 返回值:成功时返回 0;失败时返回非 0
6.3 定位到文件开头:rewind 函数
rewind
函数将文件读写指针定位到文件开头,相当于fseek(stream, 0, SEEK_SET)
。
函数原型:
c
运行
void rewind(FILE *stream);
- 参数
stream
:文件指针
示例:文件定位操作
c
运行
#include <stdio.h>
int main() {
FILE *fp;
char buffer[100];
long position;
// 创建一个测试文件
fp = fopen("position.txt", "w+");
if (fp == NULL) {
printf("无法打开文件!\n");
return 1;
}
// 写入一些内容
fprintf(fp, "C语言文件定位操作示例\n");
fprintf(fp, "这是第二行\n");
fprintf(fp, "这是第三行\n");
// 获取当前位置
position = ftell(fp);
printf("写入后当前位置: %ld 字节\n", position);
// 定位到文件开头
rewind(fp);
printf("rewind后当前位置: %ld 字节\n", ftell(fp));
// 读取第一行
fgets(buffer, sizeof(buffer), fp);
printf("读取的第一行: %s", buffer);
// 获取当前位置
position = ftell(fp);
printf("读取第一行后位置: %ld 字节\n", position);
// 从当前位置向后移动5个字节
fseek(fp, 5, SEEK_CUR);
printf("向后移动5字节后位置: %ld 字节\n", ftell(fp));
// 读取剩余内容
fgets(buffer, sizeof(buffer), fp);
printf("从新位置读取: %s", buffer);
// 定位到文件末尾前10个字节
fseek(fp, -10, SEEK_END);
printf("定位到末尾前10字节后位置: %ld 字节\n", ftell(fp));
// 读取最后10个字节
fgets(buffer, sizeof(buffer), fp);
printf("读取的最后内容: %s", buffer);
fclose(fp);
return 0;
}
输出结果:
plaintext
写入后当前位置: 43 字节
rewind后当前位置: 0 字节
读取的第一行: C语言文件定位操作示例
读取第一行后位置: 21 字节
向后移动5字节后位置: 26 字节
从新位置读取: 二行
这是第三行
定位到末尾前10字节后位置: 33 字节
读取的最后内容: 第三行
七、文件操作的错误处理
文件操作可能会出现各种错误(如文件不存在、权限不足等),良好的错误处理是编写健壮程序的重要部分。
7.1 检测文件结束:feof 函数
feof
函数判断文件是否到达末尾。
函数原型:
c
运行
int feof(FILE *stream);
- 参数
stream
:文件指针 - 返回值:如果已到达文件末尾,返回非 0 值;否则返回 0
7.2 检测错误:ferror 函数
ferror
函数检查文件操作是否发生错误。
函数原型:
c
运行
int ferror(FILE *stream);
- 参数
stream
:文件指针 - 返回值:如果发生错误,返回非 0 值;否则返回 0
7.3 清除错误标志:clearerr 函数
clearerr
函数清除文件的错误标志和文件结束标志。
函数原型:
c
运行
void clearerr(FILE *stream);
- 参数
stream
:文件指针
示例:文件操作的错误处理
c
运行
#include <stdio.h>
#include <string.h>
int main() {
FILE *fp;
char buffer[100];
// 尝试打开一个不存在的文件
fp = fopen("nonexistent.txt", "r");
if (fp == NULL) {
perror("文件打开失败"); // perror打印错误信息
return 1;
}
// 读取文件内容
if (fgets(buffer, sizeof(buffer), fp) == NULL) {
if (feof(fp)) {
printf("已到达文件末尾\n");
} else if (ferror(fp)) {
perror("读取文件时发生错误");
}
} else {
printf("读取的内容: %s", buffer);
}
// 尝试写入只读文件
if (fputs("尝试写入", fp) == EOF) {
perror("写入文件时发生错误");
clearerr(fp); // 清除错误标志
}
fclose(fp);
return 0;
}
输出结果(假设文件不存在):
plaintext
文件打开失败: No such file or directory
perror
函数会打印一个描述性的错误信息,它使用全局变量errno
来确定错误类型。errno
定义在<errno.h>
头文件中,不同的错误对应不同的数值。
八、文件操作的应用示例
8.1 示例 1:文件复制程序
下面的程序实现了文件复制功能,可以复制文本文件和二进制文件。
c
运行
#include <stdio.h>
#include <stdlib.h>
// 文件复制函数
int copy_file(const char *source_path, const char *dest_path, int is_binary) {
FILE *source_fp, *dest_fp;
int ch;
const char *source_mode = is_binary ? "rb" : "r";
const char *dest_mode = is_binary ? "wb" : "w";
// 打开源文件
source_fp = fopen(source_path, source_mode);
if (source_fp == NULL) {
perror("无法打开源文件");
return 0;
}
// 打开目标文件
dest_fp = fopen(dest_path, dest_mode);
if (dest_fp == NULL) {
perror("无法打开目标文件");
fclose(source_fp);
return 0;
}
// 复制文件内容
if (is_binary) {
// 二进制文件复制,使用fread/fwrite效率更高
char buffer[4096];
size_t bytes_read;
while ((bytes_read = fread(buffer, 1, sizeof(buffer), source_fp)) > 0) {
if (fwrite(buffer, 1, bytes_read, dest_fp) != bytes_read) {
perror("写入文件时出错");
fclose(source_fp);
fclose(dest_fp);
return 0;
}
}
if (ferror(source_fp)) {
perror("读取文件时出错");
fclose(source_fp);
fclose(dest_fp);
return 0;
}
} else {
// 文本文件复制,使用fgetc/fputc
while ((ch = fgetc(source_fp)) != EOF) {
if (fputc(ch, dest_fp) == EOF) {
perror("写入文件时出错");
fclose(source_fp);
fclose(dest_fp);
return 0;
}
}
if (ferror(source_fp)) {
perror("读取文件时出错");
fclose(source_fp);
fclose(dest_fp);
return 0;
}
}
// 关闭文件
fclose(source_fp);
fclose(dest_fp);
return 1;
}
int main(int argc, char *argv[]) {
if (argc != 3 && argc != 4) {
printf("用法: %s <源文件> <目标文件> [b]\n", argv[0]);
printf(" 复制文件,可选参数b表示复制二进制文件\n");
return 1;
}
int is_binary = (argc == 4 && argv[3][0] == 'b');
if (copy_file(argv[1], argv[2], is_binary)) {
printf("文件复制成功!\n");
return 0;
} else {
printf("文件复制失败!\n");
return 1;
}
}
这个程序接受命令行参数,支持复制文本文件和二进制文件,展示了文件操作的综合应用。
8.2 示例 2:学生成绩管理系统
下面的程序实现了一个简单的学生成绩管理系统,使用文件存储学生信息。
c
运行
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME 50
#define FILENAME "students.dat"
// 学生结构体
typedef struct {
int id;
char name[MAX_NAME];
float score;
} Student;
// 添加学生
void add_student() {
Student s;
FILE *fp;
printf("\n----- 添加新学生 -----\n");
printf("请输入学生ID: ");
scanf("%d", &s.id);
getchar(); // 吸收换行符
printf("请输入学生姓名: ");
fgets(s.name, MAX_NAME, stdin);
// 移除姓名中的换行符
s.name[strcspn(s.name, "\n")] = '\0';
printf("请输入学生成绩: ");
scanf("%f", &s.score);
// 以追加模式打开文件
fp = fopen(FILENAME, "ab");
if (fp == NULL) {
perror("无法打开文件");
return;
}
// 写入学生信息
if (fwrite(&s, sizeof(Student), 1, fp) != 1) {
perror("写入文件失败");
} else {
printf("学生信息添加成功!\n");
}
fclose(fp);
}
// 显示所有学生
void display_all_students() {
Student s;
FILE *fp;
int count = 0;
printf("\n----- 所有学生信息 -----\n");
fp = fopen(FILENAME, "rb");
if (fp == NULL) {
perror("无法打开文件");
return;
}
printf("ID\t姓名\t\t成绩\n");
printf("-------------------------\n");
// 读取所有学生信息
while (fread(&s, sizeof(Student), 1, fp) == 1) {
printf("%d\t%s\t\t%.1f\n", s.id, s.name, s.score);
count++;
}
if (count == 0) {
printf("没有学生信息!\n");
} else {
printf("-------------------------\n");
printf("共 %d 名学生\n", count);
}
fclose(fp);
}
// 查找学生
void search_student() {
Student s;
FILE *fp;
int target_id;
int found = 0;
printf("\n----- 查找学生 -----\n");
printf("请输入要查找的学生ID: ");
scanf("%d", &target_id);
fp = fopen(FILENAME, "rb");
if (fp == NULL) {
perror("无法打开文件");
return;
}
// 查找学生
while (fread(&s, sizeof(Student), 1, fp) == 1) {
if (s.id == target_id) {
printf("\n找到学生信息:\n");
printf("ID: %d\n", s.id);
printf("姓名: %s\n", s.name);
printf("成绩: %.1f\n", s.score);
found = 1;
break;
}
}
if (!found) {
printf("没有找到ID为 %d 的学生!\n", target_id);
}
fclose(fp);
}
// 菜单
void show_menu() {
printf("\n===== 学生成绩管理系统 =====\n");
printf("1. 添加学生\n");
printf("2. 显示所有学生\n");
printf("3. 查找学生\n");
printf("4. 退出\n");
printf("请选择操作 (1-4): ");
}
int main() {
int choice;
do {
show_menu();
scanf("%d", &choice);
switch (choice) {
case 1:
add_student();
break;
case 2:
display_all_students();
break;
case 3:
search_student();
break;
case 4:
printf("谢谢使用,再见!\n");
break;
default:
printf("无效的选择,请重新输入!\n");
}
} while (choice != 4);
return 0;
}
这个程序实现了一个简单的学生成绩管理系统,使用二进制文件存储学生信息,支持添加、显示和查找学生功能,展示了文件操作在实际应用中的使用。
九、总结
9.1 核心知识点回顾
- 文件操作允许程序将数据存储在外部存储设备上,实现数据的持久化
- 文件分为文本文件和二进制文件,各有适用场景
- C 语言通过文件指针(FILE*)进行文件操作
- 文件操作的基本流程:打开文件(fopen)-> 读写文件 -> 关闭文件(fclose)
- 文本文件读写函数:fgetc、fputc、fgets、fputs、fscanf、fprintf
- 二进制文件读写函数:fread、fwrite
- 文件定位函数:ftell、fseek、rewind
- 文件错误处理函数:feof、ferror、clearerr
9.2 编程思想提炼
- 持久化存储:文件操作实现了数据的持久化,使程序的数据能够在程序退出后保留
- 数据序列化:二进制文件操作实际上是数据的序列化和反序列化过程
- 资源管理:文件是一种系统资源,需要正确管理(打开后必须关闭)
- 错误处理:文件操作可能受外部因素影响(如文件不存在),必须进行错误处理
- 接口设计:文件操作函数提供了抽象接口,隐藏了不同设备和文件系统的细节
🌟个人主页:编程攻城狮
🌟人生格言:得知坦然 ,失之淡然
🌈共勉:
今天我们学习了 C 语言的文件操作,这是程序与外部世界交互的重要方式。通过文件操作,程序可以将数据存储在外部存储设备上,实现数据的持久化保存和读取。
我们学习了文件的基本概念、文件指针的使用、文件的打开与关闭、文本文件和二进制文件的读写操作、文件定位以及错误处理等内容。这些知识使我们能够编写能够存储和读取数据的实用程序。
文件操作在实际编程中应用广泛,无论是配置文件处理、数据存储还是日志记录,都离不开文件操作。掌握文件操作是编写实用程序的基础,也是从编写玩具程序向实用程序迈进的重要一步。
在下一篇内容中,我们将学习 C 语言的预处理指令,包括宏定义、文件包含、条件编译等。预处理指令是 C 语言的一个重要特性,能够在编译前对源代码进行处理,提高代码的灵活性和可维护性。
继续加油,掌握文件操作将使你能够编写更实用、更有价值的程序,处理真实世界中的数据存储和读取需求,向成为专业的程序员迈进一大步!