I'm not sure I'd want to use the following code:

Code:
 /* seek position in file to user-specified record */
            fseek( hfPtr, ( hardware.recordNum - 1 ) *
                sizeof( struct hardwareData ), SEEK_SET );

            /* write user-specified information in file */
            fwrite( &hardware, sizeof( struct hardwareData ), 1, hfPtr );
A scenario... User enters 1 for the record number of the first record BUT enters 98 for the record number of the second input record. Now you have unused space between records 1 and 98. Normally, this space is set to NULL. But if some of this space is NOT set to NULL, when you go to display all records, you may be displaying gibberish from this unused area. Also, this is a waste of storage space.

You may want to consider reading the records into a linked list or struct array, processsing the records and then writing the records back out to the file from the LL or struct array.