Thread: Writing Struct to Binary File as a Save to Disk Operation

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    12

    Writing Struct to Binary File as a Save to Disk Operation

    I've got a statistics management system that uses arrays of structures and I want to be able to close the program and reopen it without losing any data. My idea was to write all of the information to a binary file and then read it out of there each time the program is reopened.

    Ive got an array of 5 structures with an array of structs within each of them. This may complicate things...... I can't figure out how to make it work. Any suggestions????????

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<math.h>
    #include<string.h>
    
    #pragma warning (disable: 4995)
    #pragma warning (disable: 4996)
    
    FILE *out;
    #define NUMUSERS 5
    
    typedef struct rnd
    {
    	char   club[40];
    	double slope;
    	int    par;
    	int    score;
    	int    putts;
    	int    fwyHit;
    	int    grnHit;
    	int    sandSave;
    	int    numThrees;
    	int    sandAttmpt;
    	double rndHcp;
    }  ROUND;
    
    struct golfertype
    {
    	char   name[40];
    	double handicap;
    	int    totRounds;
    	char   homeClub[40];
    	double avgPutts;
    	double avgFwys;
    	double avgGreens;
    	double sandSaves;
    	int    sandRounds;
    	ROUND  rnd[100];
    };
    
    
    void PrintVitals(struct golfertype *pt);
    void EnterScore (struct golfertype *pt);
    void ViewLast10(struct golfertype *pt);
    void PrintLast10(struct golfertype *pt);
    
    
    void main()
    {
    	int choice;
    	char choice1;
    	int choice2;
    	char choice3;
    	struct golfertype *golfer;// golfer1, golfer2, golfer3, golfer4, golfer5;
    	ROUND rnd;
    	int i;
    	int a;
    	int j;
    	int numusers;
    	size_t size;
    	struct golfertype *pointer;
    	FILE *save;
    
    	save = fopen("save.dat","ab");
    	fread(&golfer, sizeof(*golfer), 1, save);
    	fclose(save);
    	
    	numusers = 5;
    	golfer   = NULL;
    
        size     = numusers *  sizeof(golfertype);
    	golfer = (golfertype *) realloc(golfer,size);
    
    	strcpy( golfer[0].name, "Andrew Holtz" );
    	golfer[0].avgFwys = 0;
    	golfer[0].avgGreens = 0;
    	golfer[0].avgPutts = 0;
    	golfer[0].handicap = 0;
    	strcpy( golfer[0].homeClub, "Pitt Meadows Golf Club" );
    	golfer[0].sandRounds = 0;
    	golfer[0].sandSaves = 0;
    	golfer[0].totRounds = 0;
    
    	strcpy( golfer[1].name, "Dan Thomson" );
    	golfer[1].avgFwys = 0;
    	golfer[1].avgGreens = 0;
    	golfer[1].avgPutts = 0;
    	golfer[1].handicap = 0;
    	strcpy( golfer[1].homeClub, "Pitt Meadows Golf Club" );
    	golfer[1].sandRounds = 0;
    	golfer[1].sandSaves = 0;
    	golfer[1].totRounds = 0;
    
    	strcpy( golfer[2].name, "Terry Salchenberger" );
    	golfer[2].avgFwys = 0;
    	golfer[2].avgGreens = 0;
    	golfer[2].avgPutts = 0;
    	golfer[2].handicap = 0;
    	strcpy( golfer[2].homeClub, "Pitt Meadows Golf Club" );
    	golfer[2].sandRounds = 0;
    	golfer[2].sandSaves = 0;
    	golfer[2].totRounds = 0;
    
    	strcpy( golfer[3].name, "Dustin Vernon" );
    	golfer[3].avgFwys = 0;
    	golfer[3].avgGreens = 0;
    	golfer[3].avgPutts = 0;
    	golfer[3].handicap = 0;
    	strcpy( golfer[3].homeClub, "Pitt Meadows Golf Club" );
    	golfer[3].sandRounds = 0;
    	golfer[3].sandSaves = 0;
    	golfer[3].totRounds = 0;
    
    	strcpy( golfer[4].name, "Jesse Kurucz" );
    	golfer[4].avgFwys = 0;
    	golfer[4].avgGreens = 0;
    	golfer[4].avgPutts = 0;
    	golfer[4].handicap = 0;
    	strcpy( golfer[4].homeClub, "Pitt Meadows Golf Club" );
    	golfer[4].sandRounds = 0;
    	golfer[4].sandSaves = 0;
    	golfer[4].totRounds = 0;
    	
    	
    	printf("\n[1] AndrewH");
    	printf("\n[2] DanT");
    	printf("\n[3] TerryS");
    	printf("\n[4] DustinV");
    	printf("\n[5] JesseK");
    
    	printf("\nPlease choose you name/profile from the list: ");
    	scanf("%d", &choice);
    
    	switch(choice)
    	{
    		case 1:
    			i=0;
    			pointer = &golfer[i];
    			break;
    
    		case 2:
    			i=1;
    			pointer = &golfer[i];
    			break;
    
    		case 3:
    			i=2;
    			pointer = &golfer[i];
    			break;
    
    		case 4:
    			i=3;
    			pointer = &golfer[i];
    			break;
    
    		case 5:
    			i=4;
    			pointer = &golfer[i];
    			break;
    
    	}
    
    	fflush(stdin);
    
    	PrintVitals( pointer );
    
    	printf("\n\n\nTo view a menu press [M], to exit press [E]");
    		scanf("%c", &choice1);
    	
    	if (choice1 == 'e' || choice1 == 'E')
    	{
    		save = fopen("save.dat", "ab");
    		fwrite(&golfer, sizeof(*golfer), 1, save);
    		fclose(save);
    		exit(1);
    	}
    		
    	else if (choice1 == 'm' || choice1 == 'M')
    	{
    	while (1)
    		{
    		
    		printf("\n\n[1] Enter a score");
    		printf("\n[2] View last 10 rnds");
    		printf("\n[3] Print out the last 10 scores");
    		printf("\n[4] View updated statistics");
    		printf("\n[5] Exit the program");
    
    		printf("\nPlease make a choice from the list: ");
    		scanf("%d", &choice2);
    		
    		fflush(stdin);
    		
    	if (choice2 == 1)
    	{
    		EnterScore( pointer );
    	}
    	
    	else if(choice2 == 2)
    	
    		ViewLast10(pointer);
    		
    	else if(choice2 == 3)
    	{
    		PrintLast10( pointer );
    	}
    	else if(choice2 == 4)
    	{
    		PrintVitals ( pointer );
    	}
    
    	else if (choice2 == 5)
    	{
    		save = fopen("save.dat", "ab");
    		fwrite(&golfer, sizeof(*golfer), 1, save);
    		fclose(save);
    		exit(1);
    	}
    	}
    
    	}
    }
    
    
    
    
    void EnterScore (struct golfertype *pt)
    {
    	int i;
    	char choice3;
    	
    		if (pt->totRounds == 0)
    			i = (pt->totRounds);
    		if (pt->totRounds > 0)
    			i = (pt->totRounds)-1;
    	
    		printf("Please enter the name of the golf club: ");
    		gets( (pt->rnd[i]).club );
    
    		fflush(stdin);
    		printf("\nPlease enter the slope of the course: ");
    		scanf("%lf", &(pt->rnd[i]).slope );
    
    		fflush(stdin);
    		printf("\nPlease enter the par of the course: ");
    		scanf("%d", &(pt->rnd[i]).par);
    
    		fflush(stdin);
    		printf("\nPlease enter the number of par 3's the course has: ");
    		scanf("%d", &(pt->rnd[i]).numThrees);
    
    		fflush(stdin);
    		printf("\nPlease enter your score: ");
    		scanf("%d", &(pt->rnd[i]).score);
    		
    		fflush(stdin);
    		printf("\nPlease enter the number of putts you had: ");
    		scanf("%d", &(pt->rnd[i]).putts);
    
    		fflush(stdin);
    		printf("\nPlease enter the number of fairways that you hit: ");
    		scanf("%d", &(pt->rnd[i]).fwyHit);
    
    		fflush(stdin);
    		printf("\nPlease enter the number of greens that you hit: ");
    		scanf("%d", &(pt->rnd[i]).grnHit);
    
    		fflush(stdin);
    		printf("\nWere you in any green side traps today?(Y/N) ");
    			scanf("%c", &choice3);
    
    		if (choice3 == 'y' || choice3 == 'Y')
    		{
    			fflush(stdin);
    			printf("\nPlease enter the sand saves you had: ");
    			scanf("%d", &(pt->rnd[i]).sandSave);
    
    			fflush(stdin);
    			printf("\nPlease enter the number of sand traps you were in: ");
    			scanf("%d" , &(pt->rnd[i]).sandAttmpt);
    
    
    			pt->sandRounds++;
    			pt->sandSaves = ((double)(pt->sandSaves) + ((double)(pt->rnd[i]).sandSave / (double)(pt->rnd[i]).sandAttmpt)) / (double)(pt->sandRounds) * 100;
    
    		}
    
    		pt->totRounds++;
    		pt->rnd[i].rndHcp = (pt->rnd[i]).score - (pt->rnd[i]).slope;
    		pt->handicap += (pt->rnd[i]).rndHcp/((double)pt->totRounds);
    		pt->avgPutts  = ((pt->avgPutts) + (double)(pt->rnd[i].putts))/((double)pt->totRounds);
    		pt->avgFwys   = ((pt->avgFwys) + ((double)(pt->rnd[i]).fwyHit / (double)(18 - (pt->rnd[i]).numThrees))) / ((double)pt->totRounds) * 100;
    		pt->avgGreens = (((pt->avgGreens) + ((double)(pt->rnd[i]).grnHit/18)) / ((double)pt->totRounds)) * 100;
    }
    
    void PrintVitals(struct golfertype *pt)
    {
    	printf("\n%s", pt->name);
    	printf("\nHomeClub: %s", pt->homeClub);
    	printf("\nHandicap: %.2lf", pt->handicap);
    	printf("\nRounds Played: %d", pt->totRounds);
    	printf("\nAverage Putts: %.2lf", pt->avgPutts);
    	printf("\nPercent Average Fairways: %.2lf ", pt->avgFwys);
    	printf("\nPercent Average Greens: %.2lf  ", pt->avgGreens);
    	printf("\nPercentage Sand Saves: %.2lf  ", pt->sandSaves);
    }
    
    void ViewLast10 (struct golfertype *pt)
    {
    	int i,j;
    
    	if (pt->totRounds > 10)
    	{
    		i = pt->totRounds - 1;
    
    		for(j=0;j<10;j++)
    		{
    			printf("\nClub: %s",(pt->rnd[i]).club);
    			printf("\nSlope: %.2lf",(pt->rnd[i]).slope);
    			printf("\nPar: %d",(pt->rnd[i]).par);
    			printf("\nScore: %d",(pt->rnd[i]).score);
    			printf("\nPutts: %d",(pt->rnd[i]).putts);
    			printf("\nFairways Hit: %d",(pt->rnd[i]).fwyHit);
    			printf("\nGreens Hit: %d",(pt->rnd[i]).grnHit);
    			printf("\nSand Saves: %d",(pt->rnd[i]).sandSave);
    			printf("\nSand Attempts: %d",(pt->rnd[i]).sandAttmpt);
    
    			i--;
    		}
    	}
    
    		if (pt->totRounds < 10)
    		{
    			i = pt->totRounds - 1;
    
    			while (i > -1)
    			{
    				printf("\nClub: %s",(pt->rnd[i]).club);
    				printf("\nSlope: %.2lf",(pt->rnd[i]).slope);
    				printf("\nPar: %d",(pt->rnd[i]).par);
    				printf("\nScore: %d",(pt->rnd[i]).score);
    				printf("\nPutts: %d",(pt->rnd[i]).putts);
    				printf("\nFairways Hit: %d",(pt->rnd[i]).fwyHit);
    				printf("\nGreens Hit: %d",(pt->rnd[i]).grnHit);
    				printf("\nSand Saves: %d",(pt->rnd[i]).sandSave);
    				printf("\nSand Attempts: %d",(pt->rnd[i]).sandAttmpt);
    
    			i--;
    			}
    		}
    	}
    	
    void PrintLast10(struct golfertype *pt)
    {
    	int i,j;
    	
    	i = pt->totRounds - 1;
    		
    	if (pt->totRounds > 10)
    	{
    		out = fopen("last10.txt", "w");
    
    		for(j=0;j<10;j++)
    		{
    			fprintf(out, "\n Club: %s",pt->rnd[i-9].club);
    			fprintf(out, "\n Slope: %.2lf",pt->rnd[i-9].slope);
    			fprintf(out, "\n Par: %d",pt->rnd[i-9].par);
    			fprintf(out, "\n Score: %d",pt->rnd[i-9].score);
    			fprintf(out, "\n Putts: %d",pt->rnd[i-9].putts);
    			fprintf(out, "\n Fairways Hit: %d",pt->rnd[i-9].fwyHit);
    			fprintf(out, "\n Greens Hit: %d",pt->rnd[i-9].grnHit);
    			fprintf(out, "\n Sand Saves: %d",pt->rnd[i-9].sandSave);
    			fprintf(out, "\n Sand Attempts: %d",pt->rnd[i-9].sandAttmpt);
    			i++;
    		}
    		fclose(out);
    	}
    	
    	if (pt->totRounds < 10)
    	{
    		out = fopen("last10.txt", "w");
    		
    		while (i > -1)
    		{
    				fprintf(out, "\nClub: %s",pt->rnd[i].club);
    				fprintf(out, "\nSlope: %.2lf",pt->rnd[i].slope);
    				fprintf(out, "\nPar: %d",pt->rnd[i].par);
    				fprintf(out, "\nScore: %d",pt->rnd[i].score);
    				fprintf(out, "\nPutts: %d",pt->rnd[i].putts);
    				fprintf(out, "\nFairways Hit: %d",pt->rnd[i].fwyHit);
    				fprintf(out, "\nGreens Hit: %d",pt->rnd[i].grnHit);
    				fprintf(out, "\nSand Saves: %d",pt->rnd[i].sandSave);
    				fprintf(out, "\nSand Attempts: %d",pt->rnd[i].sandAttmpt);
    				i--;
    			}
    			fclose(out);
    		}
    	}

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Well I'm not much of a golfer, but as long as you're not doing anything complex like sharing the data between computers, the processing for binary files is usually a combination of fread and fwrite. You just have to dump the bytes in a temporary variable of the same type that was written prior. For example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    struct record
    {
        long int product_number;
        int in_stock;
        double product_price;
        char product_name[62];
    };
    
    int main (void)
    {
        FILE * inf = NULL;
        struct record our_stock[] = 
        {
            { 
              0xBADF00D, 4, 1.99, "Bananas" 
            },
            { 
              0xDEADBEAF, 12, 15.00, "Steaks"
            },
            {
              0xDEAFD00D, 7, 2.50, "Leeks" 
            },
        };
    
        /*** Open a file in binary mode (for reading or writing). ***/
        inf = fopen("foo.bin", "wb+");
        if (inf != NULL) 
        {
            struct record aux;
            size_t idx;
            for (idx = 0; idx < sizeof our_stock / sizeof our_stock[0]; idx++) 
            {
                /*** Use fwrite to dump our bogus data into a file.  Look it up! ***/
                fwrite(&our_stock[idx], sizeof(struct record), 1, inf);
            }
    
            /*** Start reading from the beginning of the file: ***/
            rewind(inf);
            while (fread(&aux, sizeof(struct record), 1, inf) > 0) 
            {
                printf("ITEM: %-10.62s QTY: %03ld PRICE: $%6.4g ID: %-12X\n",
                    aux.product_name, aux.in_stock, aux.product_price, aux.product_number);
            }
            fclose(inf);
            remove("foo.bin");
        }
        return 0;
    }
    As expected, I've successfully written and read a binary file. The output is of little interest, but that's just to show you it's possible.

  3. #3
    Nub SWE
    Join Date
    Mar 2008
    Location
    Dallas, TX
    Posts
    133
    Don't use fflush(stdin). Undefined behavior.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 05-12-2009, 03:28 PM
  2. sequential file program
    By needhelpbad in forum C Programming
    Replies: 80
    Last Post: 06-08-2008, 01:04 PM
  3. Replies: 10
    Last Post: 05-18-2006, 11:23 PM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM