My program is reading numbers from a file- and it reads the last number twice. What is wrong with my program and what can I do to fix it?
int main()
{
ifstream inputFile;
int number = 0; //the input for the numbers in the file
double total = 0; //the total of the numbers
double counter = 0;//number of numbers
double average = 0;//average of the number
inputFile.open("random.txt");//open file
if (!inputFile)//test for file open errors
{
cout<<"Error \n";
}
while (inputFile)
{
inputFile >> number ;
total+=number;
counter++;
cout<<"The running total is: " <<total <<"\n";
}
total=total*1.00;
counter=counter*1.00;
average = total/counter;
cout<<"\nthe final total is: \t" <<total;
cout<<"\nthe number of numbers is: \t";
cout<<counter;
cout<<"\nthe average of the numbers is: \t";
cout<<setprecision(8)<< fixed<< average<<"\n";
inputFile.close();
return 0;
}
the contents of the file:
42
468
335
501
170
725
479
359
963
465
706
146
282
828
962
492
996
943
828
437
392
605
903
154
293
383
422
717
719
896
448
727
772
539
870
913
668
300
36
895
704
812
323
334
674
665
142
712
254
869
548
645
663
758
38
860
724
742
530
779
317
36
191
843
289
107
41
943
265
649
447
806
891
730
371
351
7
102
394
549
630
624
85
955
757
841
967
377
932
309
945
440
627
324
538
539
119
83
930
542
834
116
640
659
705
931
978
307
674
387
22
746
925
73
271
830
778
574
98
513
987
291
162
637
356
768
656
575
32
53
351
151
942
725
967
431
108
192
8
338
458
288
754
384
946
910
210
759
222
589
423
947
507
31
414
169
901
592
763
656
411
360
625
538
549
484
596
42
603
351
292
837
375
21
597
22
349
200
669
485
282
735
54
1000
419
939
901
789
128
468
729
894
649
484
808
422
311
618
814
515
Because the inputFile becomes false1 after an unsuccessful reading attempt has been done, and not when there’s just no more data to read. So, when you’ve read successfully the last element you are inputFile still evaluates to true, and the next iteration of the while is started. Now, at inputFile>>number the failbit is set, but you’re not checking it immediately, so your code goes on normally, “thinking” that another element has been read (when actually is just the old one which happened to remain in
number).Quick solution: move the check after the read:
or (better):
This works because operator>> returns the stream object, which is evaluated just after the read in the while condition section.
1. I know, I know that it’s not actually false but it’s operator(void*)… but don’t overcomplicate things 🙂