阅读二进制文件的C语言代码

7
如果我将一个数组写入输出文件并关闭文件,然后再次打开该文件并读取直到文件结尾,虽然文件仅包含4个数字,但程序将读取并打印5个数字,为什么?
a[0] = 4
a[1] = 7
a[2] = 12
a[3] = 34
a[4] = 34

使用十六进制编辑器打开save.bin文件

04000000 07000000 0C000000 22000000

#include <stdio.h>
#include <stdlib.h>
#define path "save.bin"

int main(void)
{
  FILE *f=NULL;
  int a[]={4,7,12,34},i,n=4,k;
  f=fopen(path,"wb");
  if(f==NULL)
  {
    perror("Error");
    exit(1);
  }
  for(i=0;i<n;i++)  // or I could use fwrite(a,sizeof(int),n,f);
    fwrite(&a[i],sizeof(int),1,f);
  fclose(f);
  f=fopen(path,"rb");
  if(f==NULL)
  {
    perror("Error");
    exit(1);
  }
  i=0;
  while(!feof(f))
  {
    fread(&k,sizeof(int),1,f);
    printf("a[%d] = %d\n",i,k);
    i++;
  }
  printf("\n");
  fclose(f);
  return 0;
}
3个回答

11
feof(fp)只有在您尝试读取文件末尾之后才会变为假(即非零值)。这就解释了为什么循环会比您预期的多执行一次。
文档中得知:
  The function feof() tests the end-of-file indicator for the stream
  pointed to by stream, returning nonzero if it is set.  The end-of-
  file indicator can be cleared only by the function clearerr().

还要阅读该帖子:为什么“while (!feof (file))”总是不正确的?


4
+1 是用来解释 feof() 如何设置的。 - hmjd

1
while(!feof(f))
{
    fread(&k,sizeof(int),1,f);
    printf("a[%d] = %d\n",i,k);  /** THIS ASSUMES fread() WAS SUCCESSFUL. **/
    i++;
}

在调用fread()后立即检查文件结尾,或者检查fread()的返回值,该返回值为读取的项目数,在这种情况下应该是1。循环的可能重构:

while(1 == fread(&k,sizeof(int),1,f))
{
    printf("a[%d] = %d\n",i,k);
    i++;
}

在循环检查后,使用feof()来确保已到达EOF并且循环没有因其他故障而结束。

1

我也有同样的问题。试试这个:

i=0;
  while(true)
  {
    fread(&k,sizeof(int),1,f);
    if(feof(f))
        break;

    printf("a[%d] = %d\n",i,k);
    i++;
  }

显然,只有在你读取文件末尾之后,feof才会返回true。当我将数组写入二进制文件时,我会先写入大小,这样当我读取它时就知道要读取的确切数据量。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接