The last entry of my file is printed twice

Pages: 12
i need help asap! my project is due in two days & i cannot fix this problem :(

code

TotalLodgements()
{
FILE *fp;
long total=0;
long previous=0;

if((fp = fopen("CLIENT---INFO.dat", "rb")) == NULL)
{
printf("\nError opening file\n\nPLEASE CONTACT CUSTOMER SERVICE AT A3 SOLUTIONS TO RESOLVE THIS PROBLEM\n");
exit(1);
}

system("cls");
while(!feof(fp))
{
fread(&newinfo, sizeof(struct client),1,fp);
printf("\n%ld",newinfo.AmtLodged);
if(previous!= newinfo.AmtLodged)
{

total=total+newinfo.AmtLodged;
}
previous = newinfo.AmtLodged;
}
time_t now;
time(&now);
printf("\nTotal Lodged as at %s : %d", ctime(&now), total); /* Print total to date */

fclose(fp); /* Close the file */

printf("\n\n");
system("pause");
system("cls");
MainMenu();
}

it prints

1000
123
1234
1234 *the problem!*

so that the total is incorrect.

CAN ANY1 HELP ME PLEASE!
Firstly, please use [code]<code goes here>[/code] tags. Secondly, please don't use system("pause") or system("cls"); you don't need either of them.
the program spans further than this module so yes i need system("pause") and cls as course requirements.
can you fix my problem?
Can you do what asked and use [code] tags so I can read your problem?

And whatever teacher or professor or whatever told you you need system(anything) is an idiot.
Read: http://cplusplus.com/forum/articles/11153/
http://cplusplus.com/forum/articles/10515/
idk what a code tag is. and im from the caribbean so its different from an american course and its 1st year programming so we hav 2 use system functions.
I already showed you how to use code tags. For a more in-depth tutorial: http://cplusplus.com/articles/firedraco1/

im from the caribbean so its different from an american course and its 1st year programming so we hav 2 use system functions.

I'm from the UK and have never taken any programming course. system() is bad, as the articles I linked you to would have explained had you read them.

All this is irrelevant -- I can't read your code because you haven't used code tags, so please, just post the code with [code] tags and I will help you.
like i said before i don't know what a code tag is....
this it?

TotalLodgements()
{
FILE *fp;
long total=0;
long previous=0;

if((fp = fopen("CLIENT---INFO.dat", "rb")) == NULL)
{
printf("\nError opening file\n\nPLEASE CONTACT CUSTOMER SERVICE AT A3 SOLUTIONS TO RESOLVE THIS PROBLEM\n");
exit(1);
}

system("cls");
while(!feof(fp))
{
fread(&newinfo, sizeof(struct client),1,fp);
printf("\n%ld",newinfo.AmtLodged);
if(previous!= newinfo.AmtLodged)
{

total=total+newinfo.AmtLodged;
}
previous = newinfo.AmtLodged;
}
time_t now;
time(&now);
printf("\nTotal Lodged as at %s : %d", ctime(&now), total); /* Print total to date */

fclose(fp); /* Close the file */

printf("\n\n");
system("pause");
system("cls");
MainMenu();
}


1000
123
1234
1234
Here.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
TotalLodgements()
{
    FILE *fp;
    long total=0;
    long previous=0;

    if((fp = fopen("CLIENT---INFO.dat", "rb")) == NULL)
    {
        printf("\nError opening file\n\nPLEASE CONTACT CUSTOMER SERVICE AT A3 SOLUTIONS TO RESOLVE THIS PROBLEM\n");
        exit(1);
    }

    system("cls");
    while(!feof(fp))
    {
        fread(&newinfo, sizeof(struct client),1,fp);
        printf("\n%ld",newinfo.AmtLodged);
        if(previous!= newinfo.AmtLodged)
        {
            total=total+newinfo.AmtLodged;
        }
        previous = newinfo.AmtLodged;
    }
    time_t now;
    time(&now);
    printf("\nTotal Lodged as at %s : %d", ctime(&now), total); /* Print total to date */

    fclose(fp); /* Close the file */

    printf("\n\n");
    system("pause");
    system("cls");
    MainMenu();
}


Output:
1000
123
1234
1234 


See the following link for information about fread:
http://www.cplusplus.com/reference/clibrary/cstdio/fread/

Stepping through this code line by line, what would happen if fread fails?
Last edited on
thnx! how'd u do tht 4 future reference?
[code]Write your code here inside the tags[/code]

You may use the <> button on the right under the heading Format: to insert the tags, if you prefer not to type them. Use the Preview button to test the results before clicking Submit.
thank u! if fread fails....i dnt kno. why wold it if the file is successfully opened?
I don't know but, if it does fail, do you think it would touch the value of newinfo or leave it as is?
Last edited on
i'd like to think it wld stay the same. newinfo is a structure declared outside this function.
So, what, then, might its value be upon failure? The previous entry?
if u omit that if statement and just have

total=total+newinfo.AmtLodged;

the result is still the same
1000
123
1234
1234 
Line 14, above:
while(!feof(fp))

This tests for EOF.

Line 16, above:
fread(&newinfo, sizeof(struct client),1,fp);

This is the call that would flag the EOF.

Line 17, above:
printf("\n%ld",newinfo.AmtLodged);

This is printing the results (even if fread fails).
Last edited on
im not sure then. what do u suggest?
Changing the order or adding an additional check so that the value is only printed when fread succeeds.

For example:
1
2
3
4
5
6
fread(&newinfo, sizeof(struct client),1,fp);     // read first value
while(!feof(fp))                                 // if not EOF
{
    printf("\n%ld",newinfo.AmtLodged);           // print value
    fread(&newinfo, sizeof(struct client),1,fp); // read next value
}


or

1
2
3
4
while( 1 == fread(&newinfo, sizeof(struct client),1,fp) )  // while fread succeeds
{
    printf("\n%ld",newinfo.AmtLodged);                     // print value
}


I prefer the second method. From the fread reference (link above), fread returns the count of entries successfully read. Since you are specifying to read 1, you want the call to return 11.

1The explicit comparison with 1 is not necessary in this case because fread is only attempting to read 1 entry. However, it should be preferred because the return value should be compared with the specified count argument. If, for example, the call to fread was changed to read 2 entries its return should be compared to 2. The problem with omitting the comparison is that fread could read only 1 out of 2 entries and return 1, which would then be interpreted as "success".
Last edited on
so basically what the second method is if fread is true print the information?

so why wasn't it working before. fread must have been true to print....
To answer your question, please review my posts and step through the previous source line by line. Expanding the loop, here's what was happening:

01. EOF? No.
02. fread? Yes, store new value (1000).
03. print value.
04. EOF? No.
05. fread? Yes, store new value (123).
06. print value.
07. EOF? No.
08. fread? Yes, store new value (1234).
09. print value.
10. EOF? No.
11. fread? No, flag EOF.
12. print value.
13. EOF? Yes.

Statements 09 and 12 both print 1234.
Pages: 12