1

the following has poped up while studying and I would like whether it does what it is supposed to. Let's say we have the following struct:

typedef struct a{
      int x;
      int y;
}a;

And we have a binary file where we can find info about multiple instances of the above struct, and we want to have an array of these structs and fill them one by one. Can we do the following?

a* aStruct= malloc(sizeof(a)*10); // aStruct[10]
a* temp;
int i = 0;
while(i < 10){
        temp = aStruct+i++;
        fread(&temp->x, sizeof(int), 1, inputFile);
        fread(&temp->y, sizeof(int), 1, inputFile);
}

Does the above means that in the end, the array aStruct will be filled with the contents from the file? If not, how can we do it?

tzegian
  • 394
  • 3
  • 13
  • 1
    [don't cast malloc](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar May 07 '19 at 15:30
  • @Barmar ok thank you. Fixed. Regarding my other question? – tzegian May 07 '19 at 15:32
  • 1
    I would use fixed-width integers (``), as you will probably know the size of each integer in the binary file, so that it isn't dependent on a specific implementation of `int`. – alx - recommends codidact May 07 '19 at 15:38
  • 2
    Also a `for` loop is more natural for this code. – alx - recommends codidact May 07 '19 at 15:39
  • 1
    While this is unlikely for the example `struct`, generalizing could lead to the possibility of padding in the struct. Then the `read` would depend on how the file was written -- the answers given so far (including OP's) would work for sequentially written members or structs with no padding. However, a struct written with padding would have to be read a `struct` at a time on an architecture with similar padding requirements, or have the padding handled explicitly. – mpez0 May 07 '19 at 15:45
  • @mpez0 True, padding should be disabled just in case. Or he could use an `intN_t[2]` instead of the struct. – alx - recommends codidact May 07 '19 at 15:49

1 Answers1

2

Yes, that should work. But there's no need for the temp variable.

for (i = 0; i < 10; i++) {
    fread(&(aStruct[i].x), sizeof aStruct[i].x, 1, inputFile);
    fread(&(aStruct[i].y), sizeof aStruct[i].y, 1, inputFile);
}

It's generally more idiomatic and easier to read if you use array indexing notation when you're using a pointer as an array.

I used sizeof aStruct[i].x rather than sizeof(int) so that it will automatically pick up the type from the structure declaration, rather than requiring you to keep them in sync if the structure changes.

Barmar
  • 741,623
  • 53
  • 500
  • 612