C,C ++从二进制文件中提取struct成员

时间:2016-09-18 09:44:42

标签: c++ c struct binary fopen

我正在使用以下代码从二进制文件中提取结构成员。

我想知道为什么会多次打印出来?当只有一个ID记录时,文件中只有一个结构。我需要访问这个成员,最好的方法是什么?

我真的不明白while循环在做什么?是否测试文件是否打开并返回1直到该点?

为什么在while循环中使用fread?

是否需要将fread设置为struct成员的特定大小?

printf语句是否正在读取二进制文件并输出一个int?

FILE *p;
struct myStruct x;
p=fopen("myfile","rb");

while(1) {
    size_t n = fread(&x, sizeof(x), 1, p);
    if (n == 0) {
        break;
    }
    printf("\n\nID:%d", x.ID);  // Use matching specifier
    fflush(stdout); // Insure output occurs promptly
}
fclose(p);
return 0;

结构如下所示:

struct myStruct
{
    int cm;    
    int bytes;          
    int ID; 
    int version; 
    char chunk[1];     
}

3 个答案:

答案 0 :(得分:1)

不是答案,而是回答评论。

只做

FILE *p = fopen("myfile","rb");
struct myStruct x;

size_t n = fread(&x, sizeof(x), 1, p);
if (n != 1) {
    // Some error message
} else {
    printf("\n\nID:%d\n", x.ID);
}

...Do as you wish with the rest of the file

答案 1 :(得分:1)

  

我想知道为什么会多次打印出来?当只有一个ID记录,而文件中只有一个结构时。

不会!因此,如果您有多个打印件,可能的解释是该文件不仅包含一个结构。另一种解释可能是文件(也就是结构)的保存方式与您用于阅读的方式不同。

  

我需要访问这个成员,最好的方法是什么?

你的方法对我来说很好。

  

我真的不明白while循环在做什么?

while存在,因为代码应该能够从文件中读取多个结构。使用while(1)意味着“永远循环”。要退出这样的循环,请使用break。在代码中break在无法从文件中读取更多结构时发生,即if (n == 0) { break; }

  

是否测试文件是否已打开并返回1直到该点?

不 - 见上面的答案。

  

为什么在while循环中使用fread?

如上所述:能够从文件中读取多个结构

  

是否需要将fread设置为struct成员的特定大小?

好吧,fread没有“设定”任何东西。它被告知要读取的元素数量和每个元素的大小。因此,您可以使用sizeof(x)调用它。

  

printf语句是否正在读取二进制文件并输出一个int?

不,阅读由fread完成。是的,printf输出小数值。

您可以尝试以下代码:

#include <stdio.h>
#include <unistd.h>

struct myStruct
{
    int cm;    
    int bytes;          
    int ID; 
    int version; 
    char chunk[1];     
};

void rr()
{
  printf("Reading file\n");

  FILE *p;
  struct myStruct x;
  p=fopen("somefile","rb");

  while(1) {
    size_t n = fread(&x, sizeof(x), 1, p);
    if (n == 0) {
      break;
    }
    printf("\n\nID:%d", x.ID);  // Use matching specifier
    fflush(stdout); // Insure output occurs promptly
  }
  fclose(p);
}

void ww()
{
  printf("Creating file containing a single struct\n");

  FILE *p;
  struct myStruct x;
  x.cm = 1;    
  x.bytes = 2;          
  x.ID = 3; 
  x.version = 4; 
  x.chunk[0] = 'a';     

  p=fopen("somefile","wb");

  fwrite(&x, sizeof(x), 1, p);
  fclose(p);
}



int main(void) {
  if( access( "somefile", F_OK ) == -1 ) 
  {
    // If "somefile" isn't there already, call ww to create it
    ww();
  }

  rr();
  return 0;
}

答案 2 :(得分:0)

答案在线

我想知道为什么会多次打印出来?当只有一个ID记录时,文件中只有一个结构。我需要访问这个成员,最好的方法是什么?

  
    

文件大小为2906字节,fread一次只读取17个字节,这在一个循环中继续

  

我真的不明白while循环在做什么?是否测试文件是否打开并返回1直到该点?

  
    

fread

返回成功读取的元素总数   

为什么在while循环中使用fread?

  
    

在这种情况下,虽然没有必要。只有一个恐惧就足够了。当正在处理来自某些其他来源(如UART)的输入并且程序必须等待所述字节数被读取时,有时会在while循环中使用Fread

  

是否需要将fread设置为struct成员的特定大小?

  
    

没有。阅读整个结构更好

  

printf语句是否正在读取二进制文件并输出一个int?

  
    

没有