Chef Flambe
Chef Flambe

Reputation: 885

Binary Files and writing Structures to them

Trying to write a function that will write my structure array to a binary file.
I thought I was able to copy it over as a complete unit one array at a time but it's not working for me.

Do I need to write each individual sub-entity or is there a way to do it in a large clump?

    {

       void export_binary(char *data_base_name, student_record *ptr,int array_flag,unsigned int rec_cnt)
    {
       if (array_flag==-99)
            {
                printf("\n\nDatabase not loaded...\n\nPlease IMPORT or CREATE a new database.\n\n");
                system("pause");
                return;
            }

    int rec_counter;
    FILE *pf;

        pf=fopen(data_base_name,"wb");

        if (!pf)
            {
                printf("*** FILE OPENING ERROR ***\n\n");
                system("pause");
                return ;
            }
        for ( rec_counter=0; rec_counter <= rec_cnt; rec_counter++)
            {
                fwrite(&ptr[rec_counter], sizeof(student_record), 1, pf);
            }


                if ((fclose(pf))!=0)
            {
                printf("\n\n*** FILE Error - Closing file FAILED! ***\n\n");
                system("pause");
                return;
            }
                printf("\n\n*** Database SAVED ***");
                system("pause");
                return;
}

Upvotes: 0

Views: 455

Answers (1)

paxdiablo
paxdiablo

Reputation: 881443

You're not actually stating what the error is (this is vitally important when you're trying to ask for help) but, provided you don't have anything like pointers in your structures, you can do it in all at once by replacing:

for ( rec_counter=0; rec_counter <= rec_cnt; rec_counter++)
{
    fwrite(&ptr[rec_counter], sizeof(student_record), 1, pf);
}

with:

int actual = fwrite (ptr, sizeof(student_record), rec_cnt, pf);
if (actual != rec_cnt) ... a problem occurred.

(you should always check the return value).

So no, you don't have to write each element of each structure in the array separately, you can go the other way and write the whole array in one hit.


As to your additional info:

I get a file that has the element of my records in it but garbage for everything else.

Yes, you will, if you write out more records than you have populated. In other words, if rec_cnt is the size of the array rather than the number of array elements you have populated, you'll have junk at the end.

I was assuming (perhaps wrongly) that rec_cnt was the number of elements populated. You should have a variable that has that value somewhere (if rec_cnt isn't it) since otherwise you don't know which elements are good and which are rubbish.

Use that variable to decide how many elements to write with fwrite.


If it's not the later array elements that are rubbish, but rather the unused space within each element, that's expected and irrelevant. Structures are allowed to have padding within them (and at the end) for alignment purposes.

Provided the padding is identical when writing and reading, you can safely ignore it.

If the alignment may be different the, yes, you'll probably have to either:

  • turn off padding for the structure (implementation-defined support such as #pragma pack); or
  • write out the fields of the structure separately to remove the padding.

Upvotes: 2

Related Questions