C语言文件随机读写通过fseekftell等函数实现文件指针的精确定位,使程序能高效访问二进制文件中的任意位置数据(如读取特定记录或修改指定内容),避免了文本文件中因字符转换导致的偏移量不准问题,是处理大型数据文件的核心技术,使用时需以二进制模式(如"rb+")打开文件并注意偏移量计算。

文件随机读写是指在读写文件时可以定位到任意位置进行读写,而不是按照文件的顺序从头到尾进行读写。这种操作在处理大型数据文件时特别有用,可以快速访问文件中的特定部分。

文件随机读写的关键函数

1. fseek 函数

  • 原型int fseek(FILE *stream, long int offset, int origin);
  • 作用:设置文件中的位置指示器位置
  • 参数
    • stream:指向FILE对象的指针
    • offset:偏移量(相对于origin的偏移)
    • origin:参考位置(SEEK_SET、SEEK_CUR、SEEK_END)
  • 返回值:成功返回0,失败返回非0

origin常量说明

  • SEEK_SET:文件开头(0)
  • SEEK_CUR:文件指针的当前位置(1)
  • SEEK_END:文件末尾(2)

2. ftell 函数

  • 原型long int ftell(FILE *stream);
  • 作用:获取文件中的位置指示器位置
  • 返回值:当前位置相对于文件开头的偏移量

3. rewind 函数

  • 原型void rewind(FILE *stream);
  • 作用:重置文件中的位置指示器位置到文件开头
  • 效果:等同于fseek(stream, 0, SEEK_SET)

4. fgetposfsetpos 函数

  • 用于获取和设置文件位置,使用fpos_t类型
  • 可以处理更大的文件偏移量,比fseekftell更灵活

文件随机读写的使用步骤

  1. 打开文件:使用适当的模式打开文件(如"rb+"用于读写二进制文件)
  2. 移动文件指针:使用fseek函数将指针移动到指定位置
  3. 进行读写操作:使用fread/fwritefgetc/fputc等函数
  4. 关闭文件:使用fclose函数关闭文件

文本文件与二进制文件的差异

  • 二进制文件:推荐使用fseek进行随机读写,偏移量计算准确
  • 文本文件:由于文本文件的转换规则,使用fseek时偏移量可能不准确,不推荐在文本文件中使用

示例代码

示例1:使用fseek读取文件特定位置

#include <stdio.h>

int main() {
    FILE *pf = fopen("test.txt", "r");
    if (pf == NULL) {
        perror("fopen");
        return 1;
    }
    
    // 读取第一个字符
    char ch = fgetc(pf);
    printf("%c\n", ch);
    
    // 将文件指针移动到当前位置后4个字节
    fseek(pf, 4, SEEK_CUR);
    
    // 读取下一个字符
    ch = fgetc(pf);
    printf("%c\n", ch);
    
    fclose(pf);
    return 0;
}

示例2:随机读写二进制文件(学生信息示例)

#include <stdio.h>
#define N 3

struct stu {
    char name[10]; // 姓名
    int num;       // 学号
    int age;       // 年龄
    float score;   // 成绩
};

int main() {
    FILE *fp;
    struct stu boys[N], boy;
    
    // 以二进制读写模式打开文件
    if ((fp = fopen("demo.txt", "wb+")) == NULL) {
        printf("Cannot open file, press any key to exit!\n");
        getchar();
        return 1;
    }
    
    printf("Input data:\n");
    for (int i = 0; i < N; i++) {
        scanf("%s %d %d %f", boys[i].name, &boys[i].num, &boys[i].age, &boys[i].score);
    }
    
    // 写入三条学生信息
    fwrite(boys, sizeof(struct stu), N, fp);
    
    // 移动文件指针到第二个学生的位置
    fseek(fp, sizeof(struct stu), SEEK_SET);
    
    // 读取第二个学生的信息
    fread(&boy, sizeof(struct stu), 1, fp);
    printf("%s %d %d %f\n", boy.name, boy.num, boy.age, boy.score);
    
    fclose(fp);
    return 0;
}

注意事项

  1. 在文本文件中使用fseek时,由于文本文件的转换规则,偏移量可能不准确
  2. fseekoffset可以是负数,表示向文件开头方向移动
  3. SEEK_END是从文件末尾之后的位置开始计算偏移量的,而不是从文件末尾的最后一个字符
  4. 对于大型文件,推荐使用二进制文件模式进行随机读写

通过以上函数,C语言可以实现灵活的文件随机读写操作,大大提高程序处理文件数据的效率和灵活性。