为什么 fread 提前到达 EOF?
我正在编写一个将文件读入内存的 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”标签的存在,但声明它“不会有任何影响”。
I am writing a C library that reads a file into memory. It skips the first 54 bytes of the file (header) and then reads the remainder as data. I use fseek to determine the length of the file, and then use fread to read in the file.
The loop runs once and then ends because the EOF is reached (no errors). At the end, bytesRead = 10624, ftell(stream) = 28726, and the buffer contains 28726 values. I expect fread to read 30,000 bytes and the file position to be 30054 when EOF is reached.
C is not my native language so I suspect I've got a dumb beginner mistake somewhere.
Code is as follows:
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;
}
Depending on the reference you use, it's quite apparent that adding a "b" to the mode flag is the answer. Seeking nominations for the bonehead-badge. :-)
This reference talks about it in the second paragraph, second sentence (though not in their table).
MSDN doesn't discuss the binary flag until halfway down the page.
OpenGroup mentions the existance of the "b" tag, but states that it "shall have no effect".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
另外值得注意的是,只需将 binmode.obj 包含到链接命令中即可为所有打开的文件执行此操作。
Also worth noting that simply including binmode.obj into your link command will do this for you for all file opens.
根据之前的答案,解决方案:
A solution, based on the previous answers:
也许这是二进制模式的问题。 尝试使用
"r+b"
作为模式打开文件。编辑:正如评论中所述,
“rb”
可能更符合您的原始意图,因为“r+b”
将打开它读/写,"rb"
是只读的。perhaps it's a binary mode issue. Try opening the file with
"r+b"
as the mode.EDIT: as noted in a comment
"rb"
is likely a better match to your original intent since"r+b"
will open it for read/write and"rb"
is read-only.