array of structures

frazzle007
frazzle007 used Ask the Experts™
on
I created a .dat file and have written 8 records into the file. Now I want to read the file and print the records sequentially. My code is working except for the fact that it keeps printing the last record twice, even though it was only entered into the file one time.
Can anyone tell me why this is happening ?
Here is my code for reading and printing the file:
#include <stdio.h>

struct checkBook {
     int check;
     char payTo[30];
     float amt;
     char description[30];
}cb;

int main()
{
     FILE *cfPtr;

     if((cfPtr=fopen("project1.dat","r"))==NULL)
          printf("File could not be opened.\n");
     
     while(!feof(cfPtr)){
        fread(&cb, sizeof(struct checkBook),1,cfPtr);

     if(cb.check != 0)
     printf("%-10d%-20s%-10.2f%s\n",cb.check,
          cb.payTo,cb.amt,cb.description);
     }    
          fclose(cfPtr);

     return 0;
}
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
Hi,
 The problem is like this.
  when last record is read, its not the end of file. This means that feof(cfPtr) if false.
   Then you try to read another record, here fread cann't read. It is at the end of file. But, 'cb' contains the data of previous record read. Hence it goes on and prints last record once again.

There could be two solutions
1. Change the sequence of fread and feof. The while loop should look like this....

 while(fread(&cb, sizeof(struct checkBook),1,cfPtr) != 0) {
       if(feof(cfPtr))
          break;

2. Reset the 'cb' in each iteration just before fread. i.e.
    memset(&cb, 0, sizeof(struct checkBook);


---Rohan
cup

Commented:
An alternative

  bytes_read = fread(&cb, sizeof(struct checkBook),1,cfPtr);
  if (bytes_read == 0) break;

After 15 years of using C, I haven't quite figured out why feof doesn't work sometimes.  However, if you check how many bytes you read in the fread, it should fix it.  It is a belt and braces approach and not very elegant but it works.

Author

Commented:
Both of these solutions work as far as not printing the last record twice, however, both are giving me another problem....It's printing out 16 lines of this:
0         0.00
and then printing my records after that. I've been trying to figure out how to get rid of those lines, without any success.
Any suggestions ?
Ensure you’re charging the right price for your IT

Do you wonder if your IT business is truly profitable or if you should raise your prices? Learn how to calculate your overhead burden using our free interactive tool and use it to determine the right price for your IT services. Start calculating Now!

Commented:
As previously mentioned, the EOF marker is not set until a read operation on a file attempts to read beyond the end of the file.  Both of the solutions above should work for that.

Your 16 lines problem is related to your changing the code somewhere else.  

For example, you will still need the if(cb.check != 0) to avoid printing out blank records stored at the beginning of the file.  (If you open the file in a hex editor you will probably find blank data before your real data.)

Here is a complete loop that should work for you:

int main()
{
    FILE *cfPtr;

    if((cfPtr=fopen("project1.dat","r"))==NULL)
         printf("File could not be opened.\n");
    else {
         while(!feof(cfPtr)){
             fread(&cb, sizeof(struct checkBook),1,cfPtr);
             if(!feof(cfPtr)){
                 if(cb.check != 0)
                   printf("%-10d%-20s%-10.2f%s\n",cb.check,
                       cb.payTo,cb.amt,cb.description);
             }
          }
       fclose(cfPtr);
    }

    return 0;
}
nrohan,
would u pls post the format of the project1.dat?
Top Expert 2006

Commented:
No comment has been added lately and this question is therefore classified abandoned.

If asker wishes to close the question, then refer to
http://www.experts-exchange.com/help/closing.jsp

Otherwise, I will leave a recommendation in the Cleanup topic area that this question is:
PAQed with A grade to nrohan

Please leave any comments here within the next seven days. It is assumed that any participant not responding to this request is no longer interested in its final disposition.

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Sunny
EE Cleanup Volunteer

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial