从二进制文件中提取结构体成员

C, C++ extract struct member from binary file

本文关键字:结构体 成员 提取 二进制文件      更新时间:2023-10-16

我使用下面的代码从二进制文件中提取一个struct成员。

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

我真的不明白while循环在做什么?它是否在测试文件是否打开并在此之前返回1 ?

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

是否需要设置为结构体成员的特定大小?

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("nnID:%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];     
}

不是真正的回答,而是回答一个评论。

只做

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("nnID:%dn", x.ID);
}
...Do as you wish with the rest of the file

我想知道为什么这个打印多次?当文件中只有一个ID记录且只有一个结构体时

它不会!因此,如果您有多个打印,可能的解释是文件包含不止一个结构体。另一种解释可能是文件(又名结构体)的保存方式与您用于读取的方式不同。

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

我觉得你的方法不错。

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

while在那里是因为代码应该能够从文件中读取多个结构体。使用while(1)意味着"永远循环"。为了摆脱这样的循环,你可以使用break。在你的代码中,break发生时,它不能从文件中读取更多的结构,即if (n == 0) { break; }

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

没有-见上面的答案。

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

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

是否需要设置为结构体成员的特定大小?

好吧,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 filen");
  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("nnID:%d", x.ID);  // Use matching specifier
    fflush(stdout); // Insure output occurs promptly
  }
  fclose(p);
}
void ww()
{
  printf("Creating file containing a single structn");
  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;
}

在线回答

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

文件大小为2906字节,而read每次只读取约17字节,这在循环中进行

我真的不明白while循环在做什么?它是否在测试文件是否打开并在此之前返回1 ?

通过read

返回成功读取的元素总数。

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

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

是否需要设置为结构体成员的特定大小?

。读取整个结构体更好

printf语句是否读取二进制并输出int?

没有