为什么恐惧会尽早到达EOF?

时间:2020-03-06 15:02:37  来源:igfitidea点击:

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

该循环运行一次,然后结束,因为达到了EOF(无错误)。最后,bytesRead = 10624,ftell(stream)= 28726,缓冲区包含28726个值。我预计到达EOF时fread会读取30,000字节,文件位置为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即可为我们打开所有文件。