I've created a program that writes info to a specific file and reading from it to generate an income report. The problem I'm having is that when I geerate my report, the last person that was entered is repeated twice, hence throwing off the grand total. Here's the bit of code:

This is how info gets to the file.

rm_num = section.room_connec.room_num;

                  fseek ( roomPtr, ( rm_num - 1 ) * sizeof( ROOM_DATA ), SEEK_SET );
         			fread ( &room, sizeof( ROOM_DATA ), 1, roomPtr );

                  // Writes to guest_history file
            		fseek( logger, ( NULL ) * sizeof( ADMISSION_DATA ), SEEK_SET );  // &&&&&&&& END
               	fread( &section, sizeof ( ADMISSION_DATA ), 1, logger );
               	section.cancel = 1; // 1 = reservation was NOT cancelled
               	section.charge = room.room_rate * .01;
               	fseek( logger, ( NULL ) * sizeof( ADMISSION_DATA ), SEEK_SET );  // &&&&&&&&  END
               	fwrite( &section, sizeof( ADMISSION_DATA ), 1, logger );
if((logger = fopen("guest_history.txt", "ab")) == NULL )
            {
            	printf("\nGuest history file could not be creted");
            }
            else
            {
            	rm_num = section.room_connec.room_num;
              	fseek ( roomPtr, ( rm_num - 1 ) * sizeof( ROOM_DATA ), SEEK_SET );
         		fread ( &room, sizeof( ROOM_DATA ), 1, roomPtr );

             	// Writes to guest_history file
            	fseek( logger, ( NULL ) * sizeof( ADMISSION_DATA ), SEEK_SET );  // &&&&&&&& END
               fread( &section, sizeof ( ADMISSION_DATA ), 1, logger );
               section.cancel = 2; // 2 = reservation was cancelled
               section.charge = room.room_rate * .01;
               fseek( logger, ( NULL ) * sizeof( ADMISSION_DATA ), SEEK_SET );  // &&&&&&&&  END
               fwrite( &section, sizeof( ADMISSION_DATA ), 1, logger );
               // end of guest_history writer

The Income Report Function

void incomereport()
{
	FILE *logger;
   float total_cancel = 0.00, total_chk_out = 0.00, grand_total = 0.00;

   if(( logger = fopen("guest_history.txt", "rb")) == NULL )
   {
   	printf("\nGuest history file could not be opened");
   	_getch();
   }
   else
   {
   	textcolor(14);
      cprintf( "---------------CHECKED-OUT GUESTS---------------" );

   	while (!feof( logger ) )
      {
      	fread( &section, sizeof (ADMISSION_DATA), 1, logger );

         if( section.cancel == 1)
         {
            printf("\n");
            textcolor(15);
            cprintf("First Name:"); printf("\t%s\n", section.first_name);
            cprintf("Last Name:"); printf("\t%s\n", section.last_name);
            cprintf("Middle I.:"); printf("\t%s\t\t", section.MI);
            cprintf("Charge:"); printf("\t\t%.2f\n", section.charge);
            cprintf("Guest Num:"); printf("\t%d\t\t", section.guest_num);
            cprintf("Duration:"); printf("\t%d\n\n", section.length_stay);
            total_chk_out += section.charge;
         }
      }

      rewind( logger );

      textcolor(14);
      cprintf( "---------------CANCELLED RESERVATIONS---------------" );

   	while (!feof( logger ) )
      {
      	fread( &section, sizeof (ADMISSION_DATA), 1, logger );

         if( section.cancel == 2)
         {
            printf("\n");
            textcolor(15);
            cprintf("First Name:"); printf("\t%s\n", section.first_name);
            cprintf("Last Name:"); printf("\t%s\n", section.last_name);
            cprintf("Middle I.:"); printf("\t%s\t\t", section.MI);
            cprintf("Charge:"); printf("\t\t%.2f\n", section.charge);
            cprintf("Guest Num:"); printf("\t%d\t\t", section.guest_num);
            cprintf("Duration:"); printf("\t%d\n\n", section.length_stay);
            total_cancel += section.charge;
         }
      }

      grand_total = total_chk_out + total_cancel;

      printf("TOTAL CANCELLATIONS:\t$ %.2f\nINCOME:\t\t\t$ %.2f\nGRAND TOTAL:\t\t$ %.2f", total_cancel, total_chk_out, grand_total);
      _getch();
	}
   fclose( logger );
}

feof() doesn't do what you think it should do.
http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1046476070&id=1043284351
feof() can only return true AFTER some other operation (say fread) has already failed. But you ignore that fread result, and thus what is left on the failed read is actually the same as the last successful read (hence the last line / record is repeated).

Use something like while ( fread( &section, sizeof (ADMISSION_DATA), 1, logger ) == 1 ) Generally speaking, you should be checking for success on all your other file operations as well.

Comments
help boost my understanding

The code you suggested doesn't work and has bugs similar to my first. With yours, some of rows that are in the file are left off (with yours the first row in each category) which lowers the grand total for my income report.

After reading that website you posted I realized that by freading it twice in the loop I'd would always be missing one. The problem is now solved. Thanks.

This question has already been answered. Start a new discussion instead.