C语言文件操作全解析:打开关闭、顺序读写与随机定位
C语言通过标准库函数实现数据的持久化存储。本文介绍如何使用`FILE`指针管理磁盘文件,涵盖按模式打开/关闭文件、常见顺序读写函数列表,以及基于偏移量`fseek`与位置获取`ftell`的随机访问机制,附带完整代码示例。
文件基础概念与作用
内存中的数据具有易失性,关机即丢失。为实现数据长久保存并便于检索,操作系统以“文件”为单位管理磁盘空间。C语言中主要关注两类文件:
- 程序文件:包含源代码(
.c)、目标文件(Windows下为.obj)及可执行程序(Windows下为.exe)。 - 数据文件:程序运行时读取或输出的非程序数据,如配置文件、日志等。
每个文件拥有唯一标识,通常由“路径+文件名主干+后缀”组成(例如:c:\code\test.txt)。在实际开发讨论中,“文件名”常泛指这一完整标识。
文件的打开与关闭
C语言通过结构体类型 FILE 维护文件信息区,包含文件名、状态及当前读写位置等。程序通过指向该结构体的指针(FILE* pf)来关联并操作文件。
第1步:指定打开模式
使用 fopen 函数打开文件,需传入文件名及打开方式。根据需求选择合适模式,常见文本与二进制模式如下表所示:
| 文件使用方式 | 含义 | 文件不存在时行为 |
|---|---|---|
| "r" (只读) | 输入,打开已存在文本文件 | 出错 |
| "w" (只写) | 输出,打开文本文件 | 新建文件 |
| "a" (追加) | 向文本文件尾添加数据 | 新建文件 |
| "rb" (只读) | 输入,打开已存在二进制文件 | 出错 |
| "wb" (只写) | 输出,打开二进制文件 | 新建文件 |
| "ab" (追加) | 向二进制文件尾添加数据 | 新建文件 |
| "r+" (读写) | 读和写,打开已存在文本文件 | 出错 |
| "w+" (读写) | 读和写,新建文本文件 | 新建文件 |
| "a+" (读写) | 在文件尾进行读写 | 新建文件 |
| "rb+" (读写) | 读和写,打开已存在二进制文件 | 出错 |
| "wb+" (读写) | 读和写,新建二进制文件 | 新建文件 |
| "ab+" (读写) | 在文件尾进行读写 | 新建文件 |
第2步:执行打开并检查状态
成功打开后,必须判断返回值是否为 NULL,以确保后续操作安全。若失败,可利用 perror 打印错误原因。
#include <stdio.h>
int main()
{
// w代表write,表示以写模式打开文件
FILE* pf = fopen("test.txt", "w");
// 判断文件是否打开成功
if(pf == NULL)
{
perror("fopen"); // 打开失败返回错误信息
return 1;
}
// ... 后续文件操作 ...
// 关闭文件,防止资源泄漏
fclose(pf);
pf = NULL; // 置为空指针,避免悬垂引用
return 0;
}文件的顺序读写
“流”是输入输出设备的抽象(如文件、网络、内存)。数据流向程序称为输入流,反之称为输出流。以下函数用于不同场景的顺序读写:
| 功能 | 函数名 | 适用范围 |
|---|---|---|
| 字符输入 | fgetc | 所有输入流 |
| 字符输出 | fputc | 所有输出流 |
| 文本行输入 | fgets | 所有输入流 |
| 文本行输出 | fputs | 所有输出流 |
| 格式化输入 | fscanf | 所有输入流 |
| 格式化输出 | fprintf | 所有输出流 |
| 二进制输入 | fread | 文件 |
| 二进制输出 | fwrite | 文件 |
写入数据示例
演示如何使用 fputc 向文本文件写入字符,每次写入后内部偏移量自动增加:
int main()
{
// 打开文件准备写入
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
// 写入字符 'a', 'b', 'c', 'd'
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fputc('d', pf);
// 操作完成,关闭文件
fclose(pf);
pf = NULL;
return 0;
}
读取数据示例
演示如何读取刚才写入的字符。调用 fgetc 后,文件指针会向后移动一位:
int main()
{
// 以只读模式打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
// 读取第一个字符 'a'
int ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}
相关函数对比:
scanf/printf 针对标准输入输出;fscanf/fprintf 针对任意流进行格式化读写;sscanf/sprintf 则用于字符串与格式化数据之间的转换。
文件的随机读写控制
当需要访问文件中间或末尾的数据时,可使用定位函数调整文件指针的位置。
步骤一:使用 fseek 定位
fseek 根据当前位置或起始位置的偏移量移动文件指针。原型为:int fseek(FILE *stream, long offset, int origin)。
origin 可选值:
- SEEK_CUR:文件指针当前位置
- SEEK_END:文件末尾位置
- SEEK_SET:文件开始位置
例如,在已存有 "abcd" 的文件中,从当前位置跳过 'b' 找到 'c':
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
// 将指针从当前位置(SEEK_CUR)向后偏移2位(跨过'b')
fseek(pf, 2, SEEK_CUR);
// 此时读取到的将是字符 'c'
int ch = fgetc(pf);
printf("%c\n", ch);
fclose(pf);
pf = NULL;
return 0;
}步骤二:使用 ftell 获取位置
ftell 返回当前文件指针相对于文件起始位置的字节偏移量,类型为 long。常用于判断文件总大小或记录当前进度:
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 2, SEEK_CUR);
int ch = fgetc(pf);
// 读取后指针向后移,此时偏移量应为 3
long pos = ftell(pf);
printf("当前偏移量: %ld\n", pos);
fclose(pf);
pf = NULL;
return 0;
}
步骤三:使用 rewind 重置
rewind 将文件指针直接重置回文件起始位置,等价于 fseek(stream, 0L, SEEK_SET):
int main()
{
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
perror("fopen");
return 1;
}
fseek(pf, 2, SEEK_CUR);
fgetc(pf); // 读取字符,指针移动
// 打印移动后的位置
long pos = ftell(pf);
printf("移动后位置: %ld\n", pos);
// 重置到文件开头
rewind(pf);
pos = ftell(pf);
printf("重置后位置: %ld\n", pos); // 输出应为 0
fclose(pf);
pf = NULL;
return 0;
}
以上就是C语言中文件操作方法(打开、关闭、顺序读写及随机定位)的详细内容,更多关于C语言文件处理的基础知识资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













