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,

Member Avatar for Mouche

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

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);
Member Avatar for Mouche

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.

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.

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.

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

sorry, but how you fixed your problem? because i got a same problem as you. i'm not sure if the inputs save properly in the file

you should know that fopen() needs "rb" for read binary. there is also + for truncate on create on some platforms, and on other plartforms it means append. on windows, fopen/fread/fwrite/fsetpos/fgetpos/fclose is 6x faster than ReadFile()

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.