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]

}

I've tried both the line you posted as well as modifying what is in the post on the FAQ, but I am still getting the last line twice.

Any idea on why I am unable to update a record? Lets say, for example, I have the following information in the file.

Record number 1
Tool name: Tool1
Quantity: 7
Cost: 1.99

When I run the update portion of the program, I can change the name, but no matter what i enter for the quantity and cost, printing the text file lists the quantity as 1074266112 and the cost as 0.00

Maybe post what you changed it to, rather than just describing the delta.
More often than not, you haven't done it.

Here I've taken the while statement in your post and replaced mine with it (line 12). Maybe I'm not quite understanding the concept, but from what I got out of the FAQ post and your post, this is how I see it.

[LIST=1]
[*]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( readPt
r ); 
[*]      fprintf( writePtr, "%-12s%-20s%-11s%10s\n", 
[*]         "Record #", "Tool Name", "Quantity","Cost" );

[*]      
[*]      while ( fread( &hardware, sizeof( struct hardwareData ), 1, readPtr ) == 1 ){ 
[*]            
[*]         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 );
[*]       
[*]   }
[/LIST]

Simple enough, works just fine now. Thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.