【问题标题】:fread returns no data in my buffer in spite of saying it read 4096 bytesfread 尽管说它读取了 4096 字节,但在我的缓冲区中没有返回任何数据
【发布时间】:2014-06-26 12:33:00
【问题描述】:

我正在移植一些从包含多个位图的文件中加载精灵的 C 代码。基本上代码 fopens 文件, fgetcs 一些标题信息,然后 freads 位图数据。我可以看到 fgetcs 正在返回正确的数据,但 fread 的结果为空。这是代码 - fname 确实存在,路径正确,fil 非零,num 是文件中的 sprite 数量(编码到 header,little-endian),pak 是 sprite 数组,sprite 是 typedef宽度、高度和位数,new_sprite 为您初始化。

FILE *fil;
uint8 *buffu;
uint8 read;
int32 x,num;
int32 w,h,c;

fil = fopen(fname, "rb");
if (!fil) return NULL;

num = fgetc(fil);
num += fgetc(fil)*256;
if (num > max) max = num;

for (x=0;x<max;x++) {
    // header
    w=fgetc(fil);
    w+=fgetc(fil)*256;
    h=fgetc(fil);
    h+=fgetc(fil)*256;
    fgetc(fil); // stuff we don't use
    fgetc(fil);
    fgetc(fil);
    fgetc(fil);
    // body
    buffu = (uint8*)malloc(w * h);
    read=fread(buffu,1,w*h,fil);
    pak->spr[x]=new_sprite(w,h);
    memcpy(pak->spr[x]->data, buffu, w*h);
    // done
    free(buffu);
}

我逐行浏览了这段代码,我可以看到 w 和 h 设置正确,并且 read=4096,这是正确的位数。但是,缓冲区在 fread 之后是 "",所以当然 memcpy 没有任何用处,我的 pak 中充满了空精灵。

我很抱歉这肯定是一个完全菜鸟的问题,但我通常使用 Cocoa,所以这种纯 C 文件处理对我来说是新的。我到处寻找 fread 的例子,它们看起来都像这里的那样——显然在 Win32 上运行良好。

【问题讨论】:

  • 如果您将缓冲区视为字符串,请注意如果看到 NUL 字节,字符串表示将被切断。最好检查原始内存以确定。
  • 天哪,如果是这样的话,我觉得我真的很笨。使用lldb,(gdb),查看原始数据的命令是什么?
  • 不,肯定都是空值,我循环打印了 buffu。
  • 为什么将read 声明为uint8?而这个变量怎么能容纳4096呢?
  • “并且 read=4096,这是正确的位数”。这里有些不对劲。 read 不能保存值 4096,fread 返回读取的项目数(此处为:字节),而不是位。

标签: c macos fread


【解决方案1】:

因为 fgetc 似乎可以工作,你可以试试这个作为测试

int each;
int byte;

//body
buffu = malloc(w * h);
for (each = 0; each < w*h; each++) {
    byte = fgetc(fil);
    if ( byte == EOF) {
        printf("End of file\n");
        break;
    }
    buffu[each] = (uint8)byte;
    printf ("byte: %d    each: %d\n", byte, each);
}
pak->spr[x]=new_sprite(w,h);
memcpy(pak->spr[x]->data, buffu, w*h);
// done

【讨论】:

  • 完美!我一直在获取数据。另一个调试器混乱。
【解决方案2】:

你说:

但是,缓冲区在 fread 之后是 "",所以当然 memcpy 没有任何用处

但这根本不是真的。 memcpy() 不是字符串函数,它会复制请求的字节数。每次。如果这不是“有用的”,那么还有其他问题。

当你的缓冲区被当作一个字符串(它不是,它是一堆二进制数据)时,如果第一个字节恰好发生在看起来就像一个空字符串为 0。剩下的 4095 个字节可以是任何值,对于 C 的字符串打印函数来说,它看起来是“空的”。

【讨论】:

  • 哪个描述了问题,但是正确查看的解决方案是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 2014-06-29
相关资源
最近更新 更多