I'm working on a problem in the File Processing chapter of my C book, and I've run into a few problems. I'm sure they are probably minor but I've been playing for a while and can't figure out why they are happening.
First: When printing a text file containing the information, the last item is always printed twice. This is around line 47
Second: when using option 2 to update a record, the name of the record updates fine but the quantity and cost do not. This part starts at line 90
Any help would be appreciated. Thanks.
[LIST=1]
[*]#include <stdlib.h>
[*]#include <stdio.h>
[*]#include<string.h>
[*]struct hardwareData {
[*] int RecordNum;
[*] char ToolName[ 15 ];
[*] int quantity;
[*] double cost;
[*]};
[*]int enterChoice( void );
[*]void textFile( FILE *readPtr );
[*]void updateRecord( FILE *fPtr );
[*]void newRecord( FILE *fPtr );
[*]void deleteRecord( FILE *fPtr );
[*]int main( void )
[*]{
[*] FILE *cfPtr;
[*] int choice;
[*]
[*] if ( ( cfPtr = fopen( "hardware.dat", "rb+" ) ) == NULL ) {
[*] printf( "File could not be opened.\n" );
[*] }
[*] else {
[*]
[*] while ( ( choice = enterChoice() ) != 5 ) {
[*] switch ( choice ) {
[*]
[*] case 1:
[*] textFile( cfPtr );
[*] break;
[*]
[*] case 2:
[*] updateRecord( cfPtr );
[*] break;
[*]
[*] case 3:
[*] newRecord( cfPtr );
[*] break;
[*]
[*] case 4:
[*] deleteRecord( cfPtr );
[*] break;
[*]
[*]
[*] default:
[*] printf( "Incorrect choice\n" );
[*] break;
[*]
[*] }
[*] }
[*] fclose( cfPtr );
[*] }
[*]
[*] system("PAUSE");
[*] return 0;
[*]}
[*]void textFile( FILE *readPtr )
[*]{
[*] FILE *writePtr;
[*]
[*] struct hardwareData hardware = { 0, "", 0, 0.0 };
[*]
[*] if ( ( writePtr = fopen( "hardware_list.txt", "w" ) ) == NULL ) {
[*] printf( "File could not be opened.\n" );
[*] }
[*] else {
[*] rewind( readPtr );
[*] fprintf( writePtr, "%-12s%-20s%-11s%10s\n",
[*] "Record #", "Tool Name", "Quantity","Cost" );
[*]
[*] while ( !feof( readPtr ) ) {
[*] fread( &hardware, sizeof( struct hardwareData ), 1, readPtr );
[*]
[*]
[*] if ( hardware.RecordNum != 0 ) {
[*] fprintf( writePtr, "%-12d%-20s%-11d%10.2f\n",
[*] hardware.RecordNum, hardware.ToolName,
[*] hardware.quantity, hardware.cost );
[*] }
[*] }
[*] fclose( writePtr );
[*] }
[*]}
[*]void updateRecord( FILE *fPtr )
[*]{
[*] int record;
[*] int newquantity=0;
[*] int newcost=0;
[*] char NewToolName[18];
[*]
[*] struct hardwareData hardware = { 0, "", 0, 0.0 };
[*]
[*] printf( "Enter record to update ( 1 - 100 ): " );
[*] scanf( "%d", &record );
[*]
[*] fseek( fPtr, ( record - 1 ) * sizeof( struct hardwareData ),
[*] SEEK_SET );
[*]
[*] fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
[*]
[*] if ( hardware.RecordNum == 0 ) {
[*] printf( "Record #%d has no information.\n", record );
[*] }
[*] else {
[*]
[*] printf( "%-12s%-20s%-11s%10s\n",
[*] "Record #", "Tool Name", "Quantity","Cost" );
[*] printf( "%-12d%-20s%-11d%10.2f\n\n",
[*] hardware.RecordNum, hardware.ToolName,
[*] hardware.quantity, hardware.cost );
[*]
[*]
[*] printf( "Enter new tool name (without spaces), Quantity, and Cost: " );
[*] scanf( "%s%d%lf", &NewToolName, &newquantity, &newcost );
[*]
[*] hardware.quantity = newquantity;
[*] hardware.cost = newcost;
[*] strcpy(hardware.ToolName, NewToolName);
[*]
[*] printf( "%-12s%-20s%-11s%10s\n",
[*] "Record #", "Tool Name", "Quantity","Cost" );
[*]
[*] printf( "%-12d%-20s%-11d%10.2f\n",
[*] hardware.RecordNum, hardware.ToolName,
[*] hardware.quantity, hardware.cost );
[*]
[*]
[*] fseek( fPtr, ( record - 1 ) * sizeof( struct hardwareData ),
[*] SEEK_SET );
[*]
[*]
[*] fwrite( &hardware, sizeof( struct hardwareData ), 1, fPtr );
[*] }
[*]}
[*]/* delete an existing record */
[*]void deleteRecord( FILE *fPtr )
[*]{
[*] struct hardwareData hardware;
[*] struct hardwareData blankHardware = { 0, " ", 0, 0 };
[*]
[*] int RecordNum;
[*]
[*] printf( "Enter record number to delete ( 1 - 100 ): " );
[*] scanf( "%d", &RecordNum );
[*]
[*] fseek( fPtr, ( RecordNum - 1 ) * sizeof( struct hardwareData ),
[*] SEEK_SET );
[*]
[*] fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
[*]
[*] if ( hardware.RecordNum == 0 ) {
[*] printf( "Record %d does not exist.\n", RecordNum );
[*] }
[*] else {
[*]
[*] fseek( fPtr, ( RecordNum - 1 ) * sizeof( struct hardwareData ),
[*] SEEK_SET );
[*]
[*] fwrite( &blankHardware,
[*] sizeof( struct hardwareData ), 1, fPtr );
[*] }
[*]}
[*]/*create new record*/
[*]void newRecord( FILE *fPtr )
[*]{
[*]
[*] struct hardwareData hardware = { 0, "", 0, 0.0 };
[*] int RecordNum;
[*]
[*] printf( "Enter new record number ( 1 - 100 ): " );
[*] scanf( "%d", &RecordNum );
[*]
[*] fseek( fPtr, ( RecordNum - 1 ) * sizeof( struct hardwareData ),
[*] SEEK_SET );
[*]
[*] fread( &hardware, sizeof( struct hardwareData ), 1, fPtr );
[*]
[*] if ( hardware.RecordNum != 0 ) {
[*] printf( "Account #%d already contains information.\n",
[*] hardware.RecordNum );
[*] }
[*] else {
[*]
[*] printf( "Enter tool name (without spaces), quantity, cost\n? " );
[*] scanf( "%s%d%lf", &hardware.ToolName, &hardware.quantity,
[*] &hardware.cost );
[*] hardware.RecordNum = RecordNum;
[*]
[*]
[*] fseek( fPtr, ( hardware.RecordNum - 1 ) *
[*] sizeof( struct hardwareData ), SEEK_SET );
[*]
[*] fwrite( &hardware,
[*] sizeof( struct hardwareData ), 1, fPtr );
[*] }
[*]}
[*]int enterChoice( void )
[*]{
[*] int menuChoice;
[*] printf( "\nEnter your choice\n"
[*] "1 - store a formatted text file of acounts called\n"
[*] " \"hardware_list.txt\" for printing\n"
[*] "2 - update a record\n"
[*] "3 - add a new record\n"
[*] "4 - delete a record\n"
[*] "5 - end program\n? " );
[*] scanf( "%d", &menuChoice );
[*] return menuChoice;
[/LIST]
}