Trouble writing to file using fwrite()

This is a discussion on Trouble writing to file using fwrite() within the C Programming forums, part of the General Programming Boards category; I have a "random-access" file, hardware.dat constructed with 100 entries. What I'm trying to do is use my setRecord() function ...

  1. #1
    Registered User
    Join Date
    May 2006
    Posts
    182

    Trouble writing to file using fwrite()

    I have a "random-access" file, hardware.dat constructed with 100 entries. What I'm trying to do is use my setRecord() function to modify one of the entrys in "hardware.dat." This is where I'm having problems. No matter what I do I can't get setRecord to modify the file. I thought it might be because I'm opening the file with the "a+" attribute but I'm not sure.


    Here is the file I used to generate my random-access file.
    Code:
    #include <stdio.h>
    
    struct record {
    int account;
    char name[ 12 ];
    int quantity;
    float price;
    };
    
    typedef struct record entry;
    
    int main()
    {
    	FILE *fPtr;
    	int i;
    	entry empty = { 0, "", 0, 0.0 };
    
    	if ( (fPtr = fopen( "hardware.dat", "w" )) == NULL ) {
    		printf( "The file hardware.dat could not be opened" );
    	}
    	else {
    		for ( i = 0; i < 100; ++i ) {
    			fwrite( &empty, sizeof( entry ), 1, fPtr );
    		}
    		fclose( fPtr );
    	}
    
    
    	return 0;
    }



    Here is the program with the setRecord function that isn't functioning.
    Code:
    #include <stdio.h>
    
    void listFile( FILE *ptr, int size );
    
    struct record {
    int account;
    char name[ 12 ];
    int quantity;
    float price;
    };
    
    typedef struct record entry;
    
    
    entry getRecord( int num, FILE *ptr );
    void setRecord( entry input, FILE *ptr );
    
    int main()
    {
    	FILE *fPtr;
    	entry tempEntry = { 99, "Eugene", 420, 64.3 };
    
    
    	if ( (fPtr = fopen( "hardware.dat", "a+" )) == NULL ) {
    		printf( "hardware.dat could not be opened\n" );
    	}
    
    	
    	setRecord( tempEntry, fPtr );
    
    
    	listFile( fPtr, 100 );
    	return 0;
    }
    
    
    
    void setRecord( entry input, FILE *ptr )
    {
    /*   -------THIS IS MY TEST PRINTF--------  */
    	printf( "%d\n", input.account );
    
    	fseek( ptr, sizeof( entry ) * input.account, SEEK_SET );
    	fwrite( &input, sizeof( entry ), 1, ptr );
    	rewind( ptr );
    
    }
    
    
    
    entry getRecord( int num, FILE *ptr )
    {
    	if ( num > 100 || num < 0 )
    		printf( "getRecord: choose account number between 0 and 99" );
    	else {
    		entry output;
    
    		fseek( ptr, sizeof( entry ) * ( num ), SEEK_SET );
    		fread( &output, sizeof( entry ), 1, ptr );
    		rewind( ptr );
    
    		return output;
    	}
    	entry temp = { 0, "", 0, 0.0 };
    	return temp;
    }
    
    
    void listFile( FILE *ptr, int size )
    {
    	entry input;
    	int i;
    
    	for ( i = 0; i < 100; ++i ) {
    		fread( &input, sizeof( entry ), 1, ptr );
    		printf( "%d%15s%10d%10.2f\n", input.account, input.name, input.quantity, input.price );
    	}
    
    	rewind( ptr );
    }

  2. #2
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You don't say exactly what is wrong, but I just tried your program out, and found two things that are potentially bad:
    1. You are not using "b" in the mode - this will be fine on some architectures, but dealing with binary files, you SHOULD indicate to the stdio file functions that you want binary format - otherwise strange things will happen.
    2. Using "a+" as the mode is probably not the right thing [in fact, it's definitely broken in my implementation of the MS Visual Studio], and using "wb+" is working fine. This is despite the fact that fseek() and ftell() appears to be done correctly.

    As a stylistic standpoint, I wouldn't do "rewind()" after every get or set operation. If some particular function wants to do rewind, then let it do that.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    182
    I have a file that generates a file, eventually I need to have the values updated in that file so I can't use the "w" attribute to fopen since that would delete the old file.

    The problem I'm having right now is I already have a file made. Now I want to use setRecord() to update a specific entry. setRecord uses the account member of the struct to know which entry to set. I'm having no luck updating the file which can be seen after I run the setRecord() function followed by the listFile() function( which lists all the entries ).


    The baffling thing is I had an example very similar to my program that does work. Same fopen attributes and all.
    Code:
    #include <stdio.h>
    
    struct clientData {
    	int acctNum;
    	char lastName[ 15 ];
    	char firstName[ 10 ];
    	double balance;
    };
    
    
    int main()
    {
    	FILE *cfPtr;
    	struct clientData client = { 0, "", "", 0.0 };
    
    	if ( ( cfPtr = fopen( "credit.dat", "a+" ) ) == NULL )
    		printf( "File could not be opened.\n" );
    	else {
    		printf( "Enter account number "
    			   " ( 1 to 100, 0 to end input )\n? " );
    		scanf( "%d", &client.acctNum );
    
    		while ( client.acctNum != 0 ) {
    			printf( "Enter lastname, firstname, balance\n? " );
    			fscanf( stdin, "%s%s%lf", client.lastName, client.firstName, &client.balance );
    			fseek( cfPtr, ( client.acctNum - 1 ) * sizeof( struct clientData ), SEEK_SET );
    			fwrite( &client, sizeof( struct clientData ), 1, cfPtr );
    			printf( "Enter account number\n? " );
    			scanf( "%d", &client.acctNum );
    		}
    
    		fclose( cfPtr );
    	}
    
    	return 0;
    }

    The system I'm using is Ubuntu Linux btw.

  4. #4
    Registered User
    Join Date
    Oct 2001
    Posts
    62
    Due to mode "a+" the new record is always appended at the end of the file. Replace 'a+' by 'w+' and your program should work.

  5. #5
    Registered User
    Join Date
    May 2006
    Posts
    182
    r+ mode made it work. w+ deleted my old dat file. Thanks guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File Writing Problem
    By polskash in forum C Programming
    Replies: 3
    Last Post: 02-13-2009, 09:47 AM
  2. Very slow file writing of 'fwrite' function in C
    By scho in forum C Programming
    Replies: 6
    Last Post: 08-03-2006, 02:16 PM
  3. Replies: 3
    Last Post: 03-04-2005, 01:46 PM
  4. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM
  5. archive format
    By Nor in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 08-05-2003, 07:01 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21