我正在从事一个项目,该项目涉及将文件中的二进制数据读取为某些数据结构。在测试期间,我看到不正确的数据正在加载到这些结构中。添加一点调试代码(使用ftell
)表明fread
并非从文件开头开始,而是在某些偏移深度(数百字节)处开始。是什么原因造成的?
我已经尝试在第一个fseek(infile, 0, SEEK_SET);
调用之前添加fread
,但是第一个调用仍以与以前相同的偏移量开始。我也尝试使用rewind(infile)
无济于事。我确实看到此问题是否发生取决于读取的文件。一些文件将始终从位置0开始,而其他文件将始终从其他偏移量开始。
这里是在我的计算机上出现此问题的代码的最小示例。我当前正在运行Windows 10,并且代码是在Visual Studio中编译的。
#include <stdio.h>
int main(int argc, char* argv[]) {
FILE* infile;
char* inname;
char x;
inname = argv[1];
if ( (fopen_s(&infile, inname, "r")) != 0) {
printf("Error opening file: %s\n", inname);
exit(1);
}
if (infile == 0) {
printf("Error opening file.\n");
exit(1);
}
while (fread(&x, sizeof(char), 1, infile) == 1) {
printf("%ld\n", ftell(infile));
printf("%hhx\n\n", x);
}
fclose(infile);
return 0;
}
您应该以二进制读取模式打开文件。
if ( (fopen_s(&infile, inname, "r")) != 0) {
到
if ( (fopen_s(&infile, inname, "rb")) != 0) {
模式字符串也可以在最后加上字母'b'字符或作为任何一个字符之间的字符上述两个字符的字符串。这是严格的与C89兼容且无效;所有的'b'都被忽略符合POSIX的系统,包括Linux。 (其他系统可能会处理>文本文件和二进制文件不同,并且添加'b'可能是a如果您对二进制文件进行I / O并希望您的程序,这是个好主意可能已移植到非UNIX环境。]