You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用fseek、fread与指针读取文件:为何fseek不改变指针地址?

关于fseek()和fread()的工作机制,以及你代码里的关键问题

嘿,我先直接点出你代码里的核心问题——你把char**类型的指针传给了需要FILE*的fread和fseek,这是完全错误的用法,会导致未定义行为(编译器大概率会报错或警告)。这也是你疑惑的根源之一,先理清这个,再解释fseek和fread的机制:

1. 先纠正你的用法错误

fread和fseek的第四个参数必须是**FILE*类型的文件流指针**,它指向标准库维护的一个文件流结构体,这个结构体里包含了文件的描述符、缓冲区、当前读取/写入的位置指示器等状态信息。而你代码里的point是char**,指向的是字符串数组,和文件流完全不是一回事,直接传递会让函数操作错误的内存区域,结果完全不可预测。

另外要注意:你定义的char *x[5]是指针数组,每个元素指向独立的字符串,这些字符串在内存中不一定是连续存储的,就算强制当成流处理,读取结果也会和预期不符。

2. 正确理解fseek()和fread()的工作逻辑

它们操作的是文件流内部的位置指示器,而不是你传入的FILE*指针本身:

  • 当你调用fread时,它会从流的当前位置指示器指向的位置读取数据,读取完成后自动把指示器向后移动对应字节数。
  • fseek的作用是修改这个流结构体里的位置指示器的值,比如你用SEEK_CUR偏移5字节,就是把当前位置加上5。但它不会改变你传入的FILE*指针的地址——因为FILE*只是指向流结构体的指针,函数修改的是结构体内部的数据,不是指针本身的地址。

举个适配你场景的正确示例(用内存流模拟文件操作,适合处理内存中连续的图像数据):

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
    char *x[5]={"axxxx","aaaa","hxxx","rrrrr","xsdsdd"};
    // 先把分散的字符串拷贝到连续内存块,模拟文件的连续内容
    char* continuous_data = malloc(64);
    if (!continuous_data) {
        perror("malloc failed");
        return 1;
    }
    int offset = 0;
    for (int i=0; i<5; i++) {
        strcpy(continuous_data + offset, x[i]);
        offset += strlen(x[i]);
    }

    char buffer[65]={0};
    // 把连续内存包装成FILE*流
    FILE* mem_stream = fmemopen(continuous_data, offset, "r");
    if (!mem_stream) {
        perror("fmemopen failed");
        free(continuous_data);
        return 1;
    }

    // 第一次读取6字节
    fread(buffer, 6, 1, mem_stream);
    printf("First read result: %s\n", buffer);

    // 从当前位置偏移5字节
    fseek(mem_stream, 5, SEEK_CUR);
    memset(buffer, 0, sizeof(buffer));
    // 第二次读取6字节
    fread(buffer, 6, 1, mem_stream);
    printf("Second read result: %s\n", buffer);

    fclose(mem_stream);
    free(continuous_data);
    return 0;
}

3. 为什么fseek不会改变指针的地址或让它递增?

  • 首先,你的point不是FILE*,所以这个问题本身基于错误的用法。但假设是正确的FILE*指针:
  • fseek接收的是FILE*的值传递(除非你传FILE**),函数内部修改的是流结构体里的位置指示器,而不是传入的指针变量本身。打个比方:你有一个结构体指针struct Person* p,你调用函数change_age(p, 20)修改结构体里的age成员,p的地址不会变,变的是p->age的值——fseek就是类似的逻辑,它修改的是FILE结构体里的位置成员,不是FILE*指针的地址。

总结一下:你混淆了内存数组指针和文件流指针的概念,fseek和fread只针对FILE*流操作,修改的是流内部的位置状态,而不是指针本身的地址。

内容的提问来源于stack exchange,提问作者IDEN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:13:51