为什么fread提前到达EOF



我正在编写一个C库,用于将文件读取到内存中。它跳过文件(头)的前54个字节,然后将剩余部分作为数据读取。我使用fseek来确定文件的长度,然后使用fread来读取文件。

循环运行一次,然后结束,因为达到了EOF(没有错误)。最后,bytesRead=10624,ftell(流)=28726,缓冲区包含28726个值。我预计当EOF到达时,fread将读取30000字节,文件位置为30054。

C不是我的母语,所以我怀疑我在某个地方犯了一个愚蠢的初学者错误。

代码如下:

const size_t headerLen = 54;
FILE * stream;
errno_t ferrno = fopen_s( &stream, filename.c_str(), "r" );
if(ferrno!=0) {
  return -1;
}
fseek( stream, 0L, SEEK_END );
size_t bytesTotal = (size_t)(ftell( stream )) - headerLen; //number of data bytes to read
size_t bytesRead = 0;
BYTE* localBuffer = new BYTE[bytesTotal];
fseek(stream,headerLen,SEEK_SET);
while(!feof(stream) && !ferror(stream)) {
    size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-bytesRead,stream);
    bytesRead+=result;
}

根据您使用的引用,很明显,在模式标志中添加一个"b"就是答案。正在寻求骨头徽章的提名。:-)

这一提法在第二段第二句中谈到了这一点(尽管不在他们的表格中)。

MSDN直到下半页才讨论二进制标志。

OpenGroup提到了"b"标签的存在,但表示其"无效"。

可能是二进制模式的问题。尝试以"r+b"作为模式打开文件。

编辑:如注释中所述,"rb"可能更符合您的初衷,因为"r+b"将打开它进行读/写,而"rb"是只读的。

还值得注意的是,只需将binmode.obj包含到链接命令中,就可以为所有打开的文件执行此操作。

基于前面答案的解决方案:

    size_t bytesRead = 0;
    BYTE* localBuffer = new BYTE[bytesTotal];
    fseek(stream,headerLen,SEEK_SET);
        while(!feof(stream) && !ferror(stream)) {
        size_t result = fread(localBuffer+bytesRead,sizeof(BYTE),bytesTotal-
        bytesRead,stream);
    bytesRead+=result;
}

相关内容

  • 没有找到相关文章

最新更新