Thread: Random Access Files...ugh.

  1. #1
    Registered User
    Join Date
    Jul 2008
    Posts
    7

    Unhappy Random Access Files...ugh.

    This is a program I wrote a few weeks ago for an online class, but it won't execute properly, and I've been trying to fix it for awhile now. The compiler doesn't give any build errors, but it will allow the user to create a tool record, but then a few problem come up... I want to try to work through them one at a time.. soo..
    Problem #1. After creating a tool record, it can be stored as a .txt file and but when you try to change its name, it returns symbols and numeric values for the integers/characters as opposed to what you changed it to as soon as you go to the next option to try to change the quantity, but it will still let you change the quantity. I think the problem lies in the STRCPY used but I'm not sure..
    I know the coding is really long, but I've bolded the areas I'm talking about... any help would be appreciated..

    Code:
    /* Tool Inventory List */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /*toolData structure definition */
    struct toolData {
    	int toolNum;   /* tool record number */
    	char name[25]; /* tool name */
    	int quantity; /* number of tools */
    	double cost; /* tool cost */
    }; /* end struct toolData */
    
    /*prototypes */
    int enterChoice( void );
    void textFile( FILE *readPtr );
    void updateName( FILE *fPtr );
    void updateQuantity ( FILE *fPtr);
    void updateCost ( FILE *fPtr);
    void updateNumber (FILE *fPtr);
    void createNew( FILE *fPtr );
    void deleteRecord( FILE *fPtr );
    
    int main (void){
    
    	FILE *tdPtr; /* tool.dat file pointer */
    	int choice; /* user choice */
        int i; /* counter */
    
    	/* create toolData with default information */
    	struct toolData blankTool = {0, "", 0, 0.0};
    	
    
    	/*fopen opens the filel exits if file can't be opened */
    	if ((tdPtr = fopen ("tool.dat", "wb")) == NULL){
    		printf("File could not be opened.\n");
    	} /* end if */
    	else{
    		/*output 100 blank records to file */
    		for (i=1; i<=100; i++){
    			fwrite( &blankTool, sizeof( struct toolData),1, tdPtr);
    		} /* end for */
    
    		fclose (tdPtr); /* closes the file */
    	}/* end else */
    
    
    	/* fopen opens the file; exits of file can't be opened */
    	if ( ( tdPtr = fopen( "tool.dat", "rb+" ) ) == NULL ){
    		printf( "File can not be opened.\n");
    	} /* end if */
    	else{
    
    		/*enable user directed action */
    		while (( choice = enterChoice() ) != 8) {
    
    			switch (choice){
    				case 1:      /* create text file from record file */
    					textFile( tdPtr );
    					break;
    
    				case 2:     /* update name*/
    					updateName ( tdPtr );
    					break;
    
    				case 3:      /* update quantity*/
    					updateQuantity (tdPtr);
    					break;
    
    				case 4:
    					updateCost (tdPtr); /* update cost */
    					break;
    
    				case 5:
    					updateNumber (tdPtr); /* update record number */
    					break;
    
    				case 6:      /* create new record */
    					createNew (tdPtr);
    					break;
    
    				case 7:     /* delete record */
    					deleteRecord (tdPtr);
    					break;
    
    				default:    /* if invalid choice is entered */
    					printf( "Sorry, incorrect choice \n");
    					break;
    			}    /* end switch */
    
    		}        /* end while */
    
    		fclose( tdPtr ); /* closes the file */
    	} /* end else */
    
    	system ("PAUSE");
    	return 0;
    }  /* end main */
    
    /* program to allow user menu choice */
    int enterChoice (void){
    
    	int menuChoice;  /* choice variable */
    
    	/* display options */
    	printf(" \nEnter your choice\n"
    		"1...Store a formatted text file of tool data called\n"
    		"    \"inventory.txt\" for printing.\n"
    		"2...Update a tool name in record.\n"
    		"3...Update a tool quantity in record.\n"[/FONT]
    		"4...Update a tool cost in record.\n"
    		"5...Update a tool record number in file.\n"
    		"6...Add a new tool record.\n"
    		"7...Delete a tool from inventory.\n"
    		"8...EXIT Program.\n? ");
    
    	scanf("%d", &menuChoice);
    
    	return menuChoice;
    }   /* end enterChoice program */
    
    /* 1...Create text file for printing */
    void textFile( FILE *readPtr){
    
    	FILE *writePtr;  /* inventory.txt file pointer */
    
    	/* create toolData with default info */
    	struct toolData tool = { 0, "", 0, 0.0 };
    
    	/* opens file; exits if file can't be opened */
    	if ((writePtr = fopen( "inventory.txt", "w")) == NULL) {
    		printf("File could not be opened.\n");
    	} /* end if */
    	
    	else {
    		rewind (readPtr); /* sets pointer location to beginning of file */
    		fprintf( writePtr, "%-6s%-16s%-11s%10s\n", "Record #", "Tool Name", "Quantity", "Cost");
    
    		/* copy all records from random-access to text file */
    		while ( !feof( readPtr )) {
    			fread( &tool, sizeof( struct toolData ), 1, readPtr);
    
    		/* write single record to text file */
    			if (tool.toolNum != 0) {
    				fprintf( writePtr, "%-6d%-16s%-11d%10.2f\n", tool.toolNum, tool.name, tool.quantity, tool.cost);
    			} /* end if */
    			
    		} /* end while */
    
    		fclose( writePtr );  /* closes the file */
    	} /* end else */
    } /* end textFile */
    
    /*2...Update a tool NAME in inventory */
    void updateName ( FILE *fPtr ){
    	int record; /* record number */
    	char newName[25]; /* new name */
    
    	/* create toolData with no information */
    	struct toolData tool = { 0, "", 0, 0.0 };
    
    	/* obtain number of tool to update */
    	printf("Enter tool to update (1-100): \n");
    	scanf( "%d", &record );
    
    	/* move file pointer to correct record in file */
    	fseek( fPtr, (record - 1) *sizeof (struct toolData), SEEK_SET);
    
    	/* read record from file */
    	fread( &record, sizeof (struct toolData), 1, fPtr);
    
    	/* display error if file doesn't exist */
    	if (tool.toolNum == 0){ 
    		printf("Record #%d has no information.\n", record);
    	} /* end if */
    	else {                 /* update NAME */
    		printf("%-6d%-16s%-11d%10.2f\n", tool.toolNum, tool.name, tool.quantity, tool.cost);
    
    		/* request name edit from user */
    		printf(" Enter new name:\n ");
    		scanf("%s", newName);
    		strcpy( tool.name, newName); /* change name */
    
    		printf("%-6d%-16s%-11d%10.2f\n", tool.toolNum, tool.name, tool.quantity, tool.cost);
    
    		/* move pointer to correct record in file */
    		fseek( fPtr, (record - 1) *sizeof (struct toolData), SEEK_SET);
    
    		/* write an updated record over old record in file*/
    		fwrite( &record, sizeof( struct toolData), 1, fPtr);
    	} /* end else */
    } /* end updateName */
    
    /*3...Update a tool QUANTITY in inventory */
    void updateQuantity ( FILE *fPtr ){
    	int record; /* record number */
    	int adjust; /* quantity adjustment */
    
    	/* create toolData with no information */
    	struct toolData tool = { 0, "", 0, 0.0 };
    
    	/* obtain number of tool to update */
    	printf("Enter tool to update (1-100): ");
    	scanf( "%d", &record );
    
    	/* move file pointer to correct record in file */
    	fseek( fPtr, (record - 1) *sizeof (struct toolData), SEEK_SET);
    
    	/* read record from file */
    	fread( &record, sizeof (struct toolData), 1, fPtr);
    
    	/* display error if file doesn't exist */
    	if (tool.toolNum == 0){ 
    		printf("Record #%d has no information.\n", record);
    	} /* end if */
    	else {                 /* update NAME */
    		printf("%-6d%-16s%-11d%10.2f\n", tool.toolNum, tool.name, tool.quantity, tool.cost);
    
    		/* request quantity edit from user */
    		printf(" Enter shipment (+) or sale (-):\n ");
    		scanf("%d", &adjust);
    		tool.quantity += adjust; /* change quantity */
    
    		printf("%-6d%-16s%-11d%10.2f\n", tool.toolNum, tool.name, tool.quantity, tool.cost);
    
    		/* move pointer to correct record in file */
    		fseek( fPtr, (record - 1) *sizeof (struct toolData), SEEK_SET);
    
    		/* write an updated record over old record in file*/
    		fwrite( &record, sizeof( struct toolData), 1, fPtr);
    	} /* end else */
    } /* end updateQuantity *
    Last edited by Salem; 07-21-2008 at 02:18 PM. Reason: replaced font with colour

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    First bit, the warnings:
    Code:
    temp.c: In function `void updateCost(FILE*)':
    temp.c:260: warning: double format, different type arg (arg 2)
    temp.c: In function `void createNew(FILE*)':
    temp.c:338: warning: char format, different type arg (arg 2)
    I don't know if that last one is related.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Given the profusion of bold, italics and underlines, I'm guessing some things like [i] have been munged into formatting, and what we're looking at isn't your code.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Jul 2008
    Posts
    7
    Quote Originally Posted by Salem View Post
    Given the profusion of bold, italics and underlines, I'm guessing some things like [i] have been munged into formatting, and what we're looking at isn't your code.
    I'm not sure what exactly you were referencing, but I cut out the extranneous code from the original post, so all that's showing now are the called programs which the error applies to. There were no italics? I'm sorry if that made it harder to look at the code, but the important parts are now in Arial just so they stand out.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Sorry to say, but Ariel font is about the worst font you could have chosen for a program. Use a plain constant width font - that's what the forum editor uses whenever you use code tags.

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    Code:
    int record; /* record number */
    	char newName[25]; /* new name */
    
    	/* create toolData with no information */
    	struct toolData tool = { 0, "", 0, 0.0 };
    
    	/* obtain number of tool to update */
    	printf("Enter tool to update (1-100): \n");
    	scanf( "%d", &record );
    
    	/* move file pointer to correct record in file */
    	fseek( fPtr, (record - 1) *sizeof (struct toolData), SEEK_SET);
    
    	/* read record from file */
    	fread( &record, sizeof (struct toolData), 1, fPtr);
    ...
    You're reading the data into an integer variable, rather than the toolData variable.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. random to int?
    By psyadam in forum C# Programming
    Replies: 7
    Last Post: 07-22-2008, 08:09 PM
  2. accessing files over wireless network
    By BobMcGee123 in forum Tech Board
    Replies: 4
    Last Post: 07-29-2006, 02:25 PM
  3. Lesson #3 - Math
    By oval in forum C# Programming
    Replies: 2
    Last Post: 04-27-2006, 08:16 AM
  4. Replies: 3
    Last Post: 09-22-2003, 09:48 PM
  5. Random Access Files
    By Unregistered in forum C Programming
    Replies: 1
    Last Post: 08-29-2001, 08:06 AM

Tags for this Thread