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

C语言中fseek与fread使用异常问题求助

问题分析与解决方案

核心问题1:文本模式的换行符转换导致字节计数偏差

你用"r"文本模式打开文件时,Windows系统会自动把文件中的\r\n换行符转换成单个\n。但fseek(f, 0, SEEK_END)获取的是磁盘上文件的原始字节数(包含所有\r),而fread读取时会跳过这些\r,导致实际读取的字符数比ftell返回的length少,剩下的缓冲区空间就会填充垃圾数据。

Python的open默认也是文本模式,但len(f.read())返回的是转换后的字符数(已经去掉了\r),所以和C语言ftell的结果自然对不上。

核心问题2:数组越界导致的未定义行为

代码中buffer[length+1] = '\0'是错误的:你malloc(length+1)申请的缓冲区,索引范围是0~length,length+1已经超出了缓冲区边界,会破坏内存结构,引发各种奇怪问题。


修复后的代码

char* get_input(const char* path) {
    char* buffer = NULL;
    FILE* f = fopen(path, "rb"); // 改用二进制模式打开,避免换行符转换

    if (f)
    {
        fseek(f, 0, SEEK_END);
        const long length = ftell(f);
        fseek(f, 0, SEEK_SET);
        printf("%ld\n", length); // 用%ld打印long类型,避免格式不匹配
        buffer = malloc(length + 1);
        if (buffer)
        {
            // 用fread的返回值确认实际读取的字节数,更安全
            size_t read_count = fread(buffer, 1, length, f);
            buffer[read_count] = '\0';
        }
        fclose(f);
    }
    return buffer;
}

额外注意事项

  • 用"rb"二进制模式打开文件后,fseek和ftell的结果会和文件实际字节数完全一致,fread也会原样读取所有内容,不会做任何转换。
  • 打印long类型的变量时,要用%ld格式符,之前的%d可能会因为类型不匹配导致输出错误(比如在64位系统上long长度大于int)。
  • 用fread的返回值设置终止符,能避免因文件读取失败(比如磁盘错误)导致的缓冲区未正确终止问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 21:13:10