使用struct读取二进制文件以查找记录

时间:2016-09-17 08:13:01

标签: c struct binary fopen

我使用以下代码读取二进制文件并使用结构输出数据。但是,我知道我的数据只包含一条记录,而且似乎打印出许多记录。我想知道为什么会这样?

 FILE *p;
 struct myStruct x;
 p=fopen("myfile","rb");
 //printf("Rcords of file:\n");
 while(1)
 {
     fread(&x,sizeof(x),1,p);
     if(feof(p)!=0)
         break;
        printf("\n\nID:%ld",x.ID);
    }
 fclose(p);
 return 0;

这样的结构很正常:

struct myStruct
{
    int ID;     
    char name[100];
}

2 个答案:

答案 0 :(得分:2)

使用%d代替%ld打印int

并查看Why is “while ( !feof (file) )” always wrong?

struct具有固定大小,您可以使用ftell来获取文件的大小,然后使用struct的大小进行划分以获取记录数另外,总是检查这些功能的结果。

类似的东西:

FILE *file;
long size;
size_t count, records;

file = fopen("myfile", "rb");
if (file == NULL) {
    perror("fopen");
    return 0;
}
if (fseek(file, 0, SEEK_END) == -1) {
    perror("fseek");
    return 0;
}
size = ftell(file);
if (size == -1) {
    perror("ftell");
    return 0;
}
if (fseek(file, 0, SEEK_SET) == -1) {
    perror("fseek");
    return 0;
}
records = size / sizeof(x);
for (count = 0; count < records; count++) {
     if (fread(&x, sizeof(x), 1, file) == 1) {
         printf("\n\nID:%d",x.ID); /* %d instead of %ld */
     } else {
         break;
     }
}

但请注意,您总是在堆栈上写入相同的变量。

编辑:

如何将struct存储在文件中?

  

我没有存储它,程序就是。

如果不属于您(您不使用相同的struct构建文件),那么您无法知道文件中的sizeof(x)是什么,请阅读结构填充和包装。

答案 1 :(得分:1)

使用更多保护。测试函数的结果。

 FILE *p;
 struct myStruct x;
 p=fopen("myfile","rb");
 assert(p); // Insure file opened

 while(1) {
   size_t n = fread(&x, sizeof(x), 1, p);
   // feof() is insufficient, 
   // fread() can fail due to input errors too and not set end-of-file condition
   // if(feof(p)!=0)
   if (n == 0) {
     break;
   }
   // printf("\n\nID:%ld",x.ID);
   printf("\n\nID:%d", x.ID);  // Use matching specifier
   fflush(stdout); // Insure output occurs promptly
 }
 fclose(p);
 return 0;

由于OP的代码具有不匹配的printf说明符,因此它表示未完全启用警告或OP正在使用弱编译器。建议修复以节省时间。