在C语言中使用ftell与fseek实现文件指针精确定位
获取文件当前位置:ftell函数详解
在C语言标准库中,ftell 函数用于查询当前文件流的读写位置。该函数定义于 stdio.h 头文件,返回值为一个 long 类型整数,表示文件指针相对于文件起始位置的字节偏移量。
long ftell(FILE *stream);
- 参数:
stream是指向已打开文件的FILE指针。 - 返回值:成功时返回当前文件指针的位置(以字节为单位),失败则返回
-1L。
示例说明:当使用 fprintf 向文件写入字符串后,文件指针会自动移动到写入内容的末尾。例如,若写入了 "This is a test"(共14个字符),此时 ftell 返回值为14,因为指针位于第15个字节处(从0开始计数)。
重定位文件指针:fseek函数用法
fseek 函数允许程序将文件指针移动到指定位置,常用于随机访问文件内容。其原型如下:
int fseek(FILE *stream, long offset, int origin);
- stream:目标文件指针。
- offset:相对于起点的偏移量(正数向前,负数向后)。
- origin:基准位置,支持三种枚举值:
-SEEK_SET(0):从文件开头计算偏移。
-SEEK_CUR(1):从当前位置计算偏移。
-SEEK_END(2):从文件末尾反向计算偏移。
典型用法示例:
fseek(fp, 100L, SEEK_SET):将指针移至距文件开头100字节处。fseek(fp, -50L, SEEK_CUR):将指针回退50字节。fseek(fp, -10L, SEEK_END):从文件末尾倒数10字节处定位。
实际应用:动态修改文件末尾数据
以下代码演示如何通过 fseek 定位到文件末尾并追加结构体数据:
#include <stdio.h>
#define N 5
typedef struct {
long id;
char name[10];
float grades[3];
} Student;
void update_last_record(const char *filename, Student new_data) {
FILE *file = fopen(filename, "rb+");
if (!file) return;
// 移动到文件末尾前一个记录的位置
fseek(file, -1L * sizeof(Student), SEEK_END);
// 写入新数据覆盖最后一个记录
fwrite(&new_data, sizeof(Student), 1, file);
fclose(file);
}
int main() {
Student students[N] = {
{10001, "MaChao", {91.0, 92.0, 77.0}},
{10002, "CaoKai", {75.0, 60.0, 88.0}},
{10003, "LiSi", {85.0, 70.0, 78.0}},
{10004, "FangFang", {90.0, 82.0, 87.0}},
{10005, "ZhangSan", {95.0, 80.0, 88.0}}
};
Student new_student = {10006, "ZhaoSi", {55.0, 70.0, 68.0}};
// 写入初始数据
FILE *fp = fopen("students.dat", "wb");
fwrite(students, sizeof(Student), N, fp);
fclose(fp);
// 更新最后一个记录
update_last_record("students.dat", new_student);
// 读取并显示更新后的数据
fp = fopen("students.dat", "rb");
Student loaded[N];
fread(loaded, sizeof(Student), N, fp);
fclose(fp);
for (int i = 0; i < N; ++i) {
printf("ID: %ld, Name: %-8s Grades: %6.2f %6.2f %6.2f\n",
loaded[i].id, loaded[i].name,
loaded[i].grades[0], loaded[i].grades[1], loaded[i].grades[2]);
}
return 0;
}