【问题标题】:C, C++ extract struct member from binary fileC, C++ 从二进制文件中提取结构成员
【发布时间】:2017-01-26 03:29:24
【问题描述】:

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

我想知道为什么这会打印多次?当只有一个 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];     
}

【问题讨论】:

  • 为什么不确定这是 C 还是 C++?你知道你是怎么编译的……对吧?
  • 我可以同时使用这两个...
  • 2906 远大于 4 个整数的大小——通常是 16 个字节——因此不止一个结构
  • 我想你已经回答了这个问题
  • @Ke。 Sorry there is one large chunk at the end I forgot to include in the struct那你应该更新你的Q,以免读者对大小不匹配感到困惑。

标签: c++ c struct binary fopen


【解决方案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

【讨论】:

  • 这是为了确保文件中只有一个结构,对吧?
  • @4386427 - 你是对的 - 我匆忙中犯了一个错误
  • @tobi303 - 不 - 但我的评论 照你做... 暗示了这一点
  • 我不太明白这个答案是什么,但我也不太明白问题是什么,那里有很多?
  • 嗨,这只是打印 ID: 0 并且我确定在 x.ID 中有一个大约 6 位数字的 ID,我可能使用了错误的类型还是什么?有什么方法可以测试 ID 成员中是否存在数据?
【解决方案2】:

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

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

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

我觉得你的方法很好。

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

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

它是否测试文件是否打开并在此之前返回 1?

否 - 请参阅上面的答案。

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

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

fread是否需要设置为struct成员的具体大小?

嗯,fread 没有“设置”任何东西。它被告知要读取多少个元素以及每个元素的 size。因此,您使用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;
}

【讨论】:

    【解决方案3】:

    在线回答

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

    文件大小为 2906 字节,fread 一次只读取 17 个字节,并且循环进行

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

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

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

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

    fread是否需要设置为struct成员的具体大小?

    没有。阅读整个结构更好

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

    没有

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-16
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多