C, C++ extract struct member from binary file

2019-10-02 01:19发布

问题:

I'm using the following code to extract a struct member from a binary file.

I'm wondering why this prints out multiple times? when there is only one ID record, and only one struct in the file. I need to access just this member, what is the best way to do it?

I don't really understand what the while loop is doing? Is it testing for whether the file is open and returning 1 until that point?

Why use fread inside the while loop?

Does the fread need to be set to the specific size of the struct member?

Is the printf statement reading the binary and outputting an 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;

The struct looks like this:

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

回答1:

Not really an answer but to answer a comment.

Just do

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


回答2:

I'm wondering why this prints out multiple times? when there is only one ID record, and only one struct in the file.

It won't! So if you have multiple prints the likely explanation is that the file contains more than just one struct. Another explanation could be that the file (aka the struct) was not saved in the same way as you use for reading.

I need to access just this member, what is the best way to do it?

Your approach looks fine to me.

I don't really understand what the while loop is doing?

The while is there because the code should be able to read multiple structs from the file. Using while(1) means something like "loop forever". To get out of such a loop, you use break. In your code the break happens when it can't read more structs from the file, i.e. if (n == 0) { break; }

Is it testing for whether the file is open and returning 1 until that point?

No - see answer above.

Why use fread inside the while loop?

As above: To able to read multiple structs from the file

Does the fread need to be set to the specific size of the struct member?

Well, fread is not "set" to anything. It is told how many elements to read and the size of each element. Therefore you call it with sizeof(x).

Is the printf statement reading the binary and outputting an int?

No, the reading is done by fread. Yes, printf outputs the decimal value.

You can try out this code:

#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:

Answers in-line

I'm wondering why this prints out multiple times? when there is only one ID record, and only one struct in the file. I need to access just this member, what is the best way to do it?

The file size is 2906 bytes and fread is only reading sone 17 bytes at a time, and this goes on in a loop

I don't really understand what the while loop is doing? Is it testing for whether the file is open and returning 1 until that point?

The total number of elements successfully read is returned by fread

Why use fread inside the while loop?

In this case while is not necessary. just one fread is enough. Fread is sometimes used in a while loop when input from some other source like UART is being processed and the program has to wait for the said number of bytes t be read

Does the fread need to be set to the specific size of the struct member?

No. Reading the entire struct is better

Is the printf statement reading the binary and outputting an int?

No