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

使用fread读取GLSL着色器文件时多出6个字符的问题咨询

fread读取GLSL文件多出字符的问题分析与解决

原因分析

  • 未检查文件打开状态:如果fopen因路径错误、权限不足等原因失败,fshader会返回NULL,后续fseek、ftell、fread的操作都是未定义行为,得到的fsize是随机值,malloc分配的空间大小错误,最终读取到内存中的垃圾数据(比如你看到的_to_te)。
  • 文本模式的换行转换:在Windows系统中,用"r"文本模式打开文件时,系统会自动将文件中的\r\n(Windows换行)转换为\n(Unix换行),这会导致ftell获取的文件实际字节数大于fread实际读取的字符数。此时直接按fsize设置字符串终止符,会把内存中未被fread填充的垃圾区域包含进来。
  • 未校验fread的实际读取量:fread不一定能读取到fsize个字节(比如文件读取中途出错),直接用fsize设置终止符会导致未初始化的内存内容被当成有效数据。

解决方法

1. 使用二进制模式打开文件

将fopen的模式改为"rb",禁用系统的换行符转换,让ftell获取的大小与fread读取的字节数完全匹配:

fshader = fopen("src/graphics/_fragment.shader", "rb");

2. 完善错误检查逻辑

为每一步IO操作添加错误校验,避免未定义行为:

FILE *fshader = fopen("src/graphics/_fragment.shader", "r");
if (!fshader) {
    perror("Failed to open fragment shader");
    return -1;
}

if (fseek(fshader, 0L, SEEK_END) != 0) {
    perror("Failed to seek file end");
    fclose(fshader);
    return -1;
}

long fsize = ftell(fshader);
if (fsize == -1) {
    perror("Failed to get file size");
    fclose(fshader);
    return -1;
}
rewind(fshader);

char *fbuffer = (char *)malloc(fsize + 1);
if (!fbuffer) {
    perror("Failed to allocate memory");
    fclose(fshader);
    return -1;
}

size_t read_bytes = fread(fbuffer, 1, fsize, fshader);
// 用实际读取的字节数设置字符串终止符,避免垃圾数据
fbuffer[read_bytes] = '\0';

// 使用后记得清理资源
fclose(fshader);
// ... 使用fbuffer ...
free(fbuffer);

3. 更可靠的动态读取方式(推荐)

避免依赖fseek和ftell,改用getline动态读取文件内容,自动处理内存分配和换行符:

FILE *fshader = fopen("src/graphics/_fragment.shader", "r");
if (!fshader) {
    perror("Failed to open shader file");
    return -1;
}

char *fbuffer = NULL;
size_t buffer_capacity = 0;
ssize_t read_len;

// 逐行读取,getline会自动扩展缓冲区
while ((read_len = getline(&fbuffer, &buffer_capacity, fshader)) != -1) {
    // 可在此处理每行内容,或直接使用拼接后的fbuffer
}

// 使用fbuffer进行后续操作...

fclose(fshader);
free(fbuffer);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 20:23:12