954,492 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Help with File I/O as Binary file C, array of structure

Hey guys,
I would like some help regarding saving or reading to or from a bin file.
I've read several online tutorials about file input/output, however it doesn't given specific information when applying it to both an array of structures. My knowledge of pointers is weak, as I constantly need to look over examples to get an idea of whats going on.

Heres my attempt:

#define PLANET_SIZE 10
/* Called from function */
save(planet_t writePlanet[], *totalSize); /* define as int* totalSize */
read(planet_t *writePlanet);

typedef struct{
  char name[20];
}planet_t;

/* Save to file */
void save(planet_t writePlanet[], int totalSize){
   FILE *outFile;
   int count;

   outFile = fopen("planet.bin", "wb");

   if(outFile==NULL){
      printf("\nFile error.");
   }
   else{
      for(count = 0; count<PLANET_SIZE; count++){ /**/
         fwrite( &writePlanet, sizeof(writePlanet), 1, outFile);
         printf("\n%s", writePlanet[count].name); /* Test to see if its writing. */
      }
      fclose(outFile);
   }
   getchar();
}

/* Read from file */
void readFleet(planet_t *writePlanet){
   FILE *inFile;
   int count;
   inFile = fopen("planet.bin", "rb");

   if(inFile == NULL){
      printf("\nFile error.");
   }
   else {
      for(count = 0; count < PLANET_SIZE; count++){
         fread(&writePlanet, sizeof(writePlanet), 1, inFile);
         printf("\nPlanet name:\t%s", writePlanet[count].name);
      }
   }
   fclose(inFile);
   getchar();
}

My problem is that im not sure if its reading or saving properly.
I'm definitely sure its not reading from file properly.

Its an assignment and would prefer not to reveal any further code unless neccessary, however I am really stuck on this problem.
My first thought of a solution was to have another array of struct which would at the end of 'void read' copys value over to the original array of struct, however I think my problem lies when passing the array of struct to 'void read'.


Would appreciate any help or useful links.
Cheers,

john10
Newbie Poster
17 posts since Apr 2010
Reputation Points: 10
Solved Threads: 0
 

You're writing the entire array writePlanet each time you call save(). You can either write the entire array once or write each planet by using indices to specify which planet in writePlanet to write.

For example:

for (count = 0; count < PLANET_SIZE; count++) {
    fwrite(&writePlanet[i], sizeof(writePlanet[i]), 1, outFile);
}


Again, in readFleet(), you're reading the entire array multiple times into writePlanet.

A good way to check if your fwrite() calls are working correctly is to look at the binary file with a program that will give you a dump of the file in characters. In linux, you can use od.

Here, I used it to three char arrays:

>> od -Ad -w10 -c planet.bin
0000000   E   a   r   t   h  \0  \0  \0  \0  \0
0000010  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000020   M   a   r   s  \0  \0  \0  \0  \0  \0
0000030  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000040   V   e   n   u   s  \0  \0  \0  \0  \0
0000050  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000060
LaMouche
Posting Whiz in Training
269 posts since Oct 2006
Reputation Points: 83
Solved Threads: 39
 

With regards to reading the planet from file, is the correct argument/parameter being passed, so that it changing the original planet array?

so essentially

for (count = 0; count < PLANET_SIZE; count++) {
    fwrite(&writePlanet[i], sizeof(writePlanet[i]), 1, outFile);
}

is the same as

fwrite(&writePlanet, sizeof(writePlanet), PLANET_SIZE, outFile);
john10
Newbie Poster
17 posts since Apr 2010
Reputation Points: 10
Solved Threads: 0
 

Ah, I don't think so. For fread(), you need to pass the address of the block you want to write to for the first argument. You're passing the address of the pointer. Try passing the address of the block writePlanet is pointing to like this:

&(*writePlanet)


That should also be the same as just passing writePlanet by itself, so you could do that, too.

LaMouche
Posting Whiz in Training
269 posts since Oct 2006
Reputation Points: 83
Solved Threads: 39
 
You're writing the entire array writePlanet each time you call save().

No. OP is writing a same nonsensical pointer multiple times. Here is the essential code:

void save(planet_t writePlanet[], int totalSize){
      for(count = 0; count<PLANET_SIZE; count++){ /**/
         fwrite( &writePlanet, sizeof(writePlanet), 1, outFile);
         printf("\n%s", writePlanet[count].name); /* Test to see if its writing. */
      }


writePlanet is a pointer. &writePlanet is a pointer to it (an address of some location in the save() 's stack frame). sizeof(writePlanet) is a size of a pointer.

To write the entire array, do

fwrite(writePlanet, sizeof(*writePlanet), totalSize, outFile)

assuming that totalSize is a number of entries to be written.

Same stays for read.

nezachem
Posting Shark
903 posts since Dec 2009
Reputation Points: 719
Solved Threads: 194
 
Same stays for read.


Just to clarify, read is

fread(writePlanet, sizeof(*writePlanet), PLANET_SIZE, inFile);

Sorry if its wrong, I'm still confused about pointers when to comes to structures and arrays as they are still new to me.

john10
Newbie Poster
17 posts since Apr 2010
Reputation Points: 10
Solved Threads: 0
 

Found a different solution which fixed my problem, thanks for the help.

john10
Newbie Poster
17 posts since Apr 2010
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You
View similar articles that have also been tagged: