While !End of File terminating program premature

Hello
My code is terminating prematurely due to while !eof
Please check and advise, thank you.

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
   
//Write a program that takes its input from a file of numbers of type double.
//The program outputs to the screen the average and the standard deviation of the numbers in the file.
//The file contains nothing but numbers of type double separated by blanks and/or line breaks.
//The standard deviation of a list of numbers n1, n2, n3, and so forth is defined as the square root of
//the average of the following numbers:
//(n1 – a)2, (n2 – a)2, (n3 – a)2, and so forth
//The number a is the average of the numbers n1, n2, n3, and so forth.
//Hint: Write your program so that it first reads the entire file and computes the average of all the numbers,
// and then closes the file, then reopens the file and computes the standard deviation

#include <iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cmath>

using namespace std;
int stdDeviation( double n[], int avg) // computes the standard deviation
{

    int i;
    double sd = 0;
    cout.setf(ios::fixed);
    sd=sqrt(pow((n[i]-avg),2));



    return (sd);
}
int main()
{
ifstream fin;
ofstream fout;

//cout.setf(ios::showpoint);
//create input file  , read data , compute the sum, count the numbers , calculate average , calculate stdDev

fin.open("inputFile.dat");
if ( fin.fail())
{
    cout<<" Error in Opening Input File .......'\n"<<endl;
}
    else
    {
    cout<<"  Opening Input File '\n";
    exit(1);
    }

//}
fout.open("outputFile",ios::app);
if ( fout.fail())
{
    cout<<" Error in creating Output file.....'\n";
}
else
{
    cout<<" Creating output File '\n";
}


double n1,n2,n3,n4,n5,inputNo[6],sum = 0;
int i,average = 0,  count = 0 , stdDev = 0 ;
cout.setf(ios::fixed);
setw(6);

do
{
     //inputData= fin.get("inputFile.dat");
for ( i=0; i<= count; i++)
    {
    sum += inputNo[i];
    count++;
    average = sum / count;
    }

}
while (!=fin.eof())
{
   fin>>n1>>n2>>n3>>n4>>n5;
   stdDev = stdDeviation( inputNo, average);

{
    cout<<" End of File... Terminating ...!"<<endl;
}
fout<<" The output is as follows ; '\n";
fout<<n1<<n2<<n3<<n4<<n5<<endl;
fout<<" The total sum is "<<sum<< endl;
fout<<" while the average is "<<average<<endl;
fout<<" for the total of "<<count<<" numbers computed "<<endl;
fout<<" Standard deviation is "<< stdDev<<endl;

    fin.close( );
    fout.close( );
    return 0;

}
Last edited on
Line 78 is wrong. To test for end-of-file, it would be while (!fin.eof()). But that has several problems. First, the stream doesn't know it's at the end of file until it actually tries to read past that point, which won't happen until you attempt to read it. Second, this won't catch problems like syntax errors, which will make the stream unusable in the middle of the file, and you won't ever get to the end.

To check for all errors you'd do while (fin). This Checks if the stream is bad for any reason. It works because the stream class has an operator that converts it to a bool. The operator returns the equivalent of !fail(). But you're still left with the problem that you really want to check it after reading the number. A great way to handle this is to read the number inside the while condition:
while (fin >> n) fin >> n extracts n and returns a reference to fin. Then the conversion to bool takes place, which calls fin.fail(). Pretty cool huh?

That's the good news. The bad news is that your program has several problems.

It's coded right now to read and write to specific file names. Can you use cin and cout instead? That way it could real/write whatever file you want. If you coded it this way then you could run it with myProg < inputFile.dat > outputFile.dat to do what you have now.

Lines 67-78 are trying to compute the average but you haven't read the numbers yet.

Line 80 is trying to read exactly 5 numbers. I think the point of the assignment is to read however many numbers are needed.

Here is my advice:

1. Save your current code for reference, but then start over.
2. Write a program that reads numbers from cin and prints them to cout. The point is to write the code that reads all the numbers.
3. Once that code is working, modify it to compute the sum as you read the numbers. When all numbers are read, compute the average and print it out.
4. When that's done, add code to re-read the file and compute the standard deviation. Better yet, be a classroom hero and figure out how to compute the standard deviation as you're reading the numbers the first time. I think you'll find that if you store the sum of the numbers and the sum of their squares then you can do it.

Good luck!
Thank for your quick response, i have taken your advice and am working on it

However please advise me how i can declare an array whose size is unknown and can only be determined after input without getting an error from the complier.
Use a std::vector instead of the array would be the best choice. Another method would be to use new to allocate the array with the user supplied array size.

The point is that you don't need an array at all. Using the hint in the assignment, you can compute the answers by storing just the sum of the values and the average, but you have to make two passes through the input file. Using my method, you can in one pass if you store both the sum of values, and the sum of the squares of the values. You'll have to work out the details of computing the standard deviation from these values with a little algebra, but it can be done.
Ok i have made some changes but am not sure if its working fine please advise

#include <iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cmath>
using namespace std;
// Program reads input from a file with numbers of type double
// sums them up, computes their average and standard deviation
int main()
{
ifstream fin;
fin.open("inputData.dat");
ofstream fout;
fout.open("outputData.dat");

double next, sum = 0 ;
int count = 0, avg = 0, stdDev = 0, variance;

while(fin >> next)
{
cout<<setw(6)<<next<<endl;

}
while (fin >> next )
{

fin>>next;
sum = sum + next;
count ++;
avg = sum / count ;
variance = pow((avg - next),2);
stdDev = sqrt(variance);
cout<<" The Average of the numbers is "<<avg<<endl;
cout<<" whilst their standard deviation is "<<stdDev<<endl;
}

fin.close();
fout.close();

return 0;

}
You're making great progress.

A quick note: when posting code, please use code tags. Highlight the code and click the <> button to the right of the edit window. This will add line numbers so we can refer to it. Here is your code indented and with code tags:
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
35
36
37
38
39
40
41
#include <iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cmath>
using namespace std;
// Program reads input from a file with numbers of type double
// sums them up, computes their average and standard deviation
int
main()
{
    ifstream fin;
    fin.open("inputData.dat");
    ofstream fout;
    fout.open("outputData.dat");

    double next, sum = 0;
    int count = 0, avg = 0, stdDev = 0, variance;

    while (fin >> next) {
	cout << setw(6) << next << endl;

    }
    while (fin >> next) {

	fin >> next;
	sum = sum + next;
	count++;
	avg = sum / count;
	variance = pow((avg - next), 2);
	stdDev = sqrt(variance);
	cout << " The Average of the numbers is " << avg << endl;
	cout << " whilst their standard deviation is " << stdDev << endl;
    }

    fin.close();
    fout.close();

    return 0;

}

You correctly have two passes through the code but you need to compute the average in the first loop, and then compute the variance in the second loop (unless you do the math and figure out how to do it in one pass. It's just a little algebra).

Okay, even if the input numbers are integers, avg, variance and stdDev can be real numbers, so make them doubles instead of ints.

To compute the average in the first loop, you need to move lines 27-29 there. Actually, line 29 can go after the loop:
We might as well put line 32 after the first loop too:
1
2
3
4
5
6
7
    while (fin >> next) {
        cout << next << '\n';
        sum = sum + next;
        count++;
    }
    avg = sum / count;
    cout << " The Average of the numbers is " << avg << endl;

To rewind the input file, add this before line 24:
1
2
    fin.clear();                // clear eof flag
    fin.seekg(0);               // reposition to beginning of file 

Remove line 26. You read the value at line 24.

That leaves the code to compute the variance and standard deviation. Re-read the formulas for these values: your code doesn't compute them correctly and you'll need to fix that.
thank you for your patience and response, i am encouraged to learn fast ...

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

#include <iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cmath>
#include<initializer_list>
using namespace std;
// Program reads input from a file with numbers of type double
// sums them up, computes and displays their average and standard deviation
// on the screen
int main()
{
    ifstream fin;
    fin.open("inputData.dat");
    ofstream fout;
    fout.open("outputData.dat");

    double next, sum = 0, avg = 0, stdDev = 0,  variance ;
    int i, numbers ;


for( i = 0; i < numbers.size(); i++)
{
    sum += numbers[i];
}

avg = sum / numbers.size();

    while(fin >> next)
    {
        cout<<setw(6)<<next<<endl;
        sum = sum + next;
       // count ++;
        avg =  sum / numbers.size() ;
    }
    fin.clear()         // clear eof flag
    fin.seek(0)         // go to the beginning of the file

    while (fin >> next )
    {
        variance = pow((avg - next),2);
        stdDev = sqrt(variance);
        cout<<" The Average of the numbers is "<<avg<<endl;
        cout<<" whilst their standard deviation is "<<stdDev<<endl;
    }
vector <double> numbers;     // to store all the numbers in inputData.dat
    while(fin >> next)
{
    numbers.push_back(next);    // insert next into the vector
}
for( i = 0; i < numbers.size(); i++)
{
    sum += numbers[i];
}
average = sum / numbers.size();
    fin.close();
    fout.close();

    return 0;

}

Lines 23-28. What is the purpose of these lines? You haven't read the data yet or even declared the numbers vector?

Line 35: Why do you compute the average after reading each number? You should wait until after the loop, just like I showed.

Lines 42-43: I repeat:
Re-read the formulas for these values: your code doesn't compute them correctly and you'll need to fix that.


Lines 47-56: What's all this? Why is it here?
Hello
how do i get the code to compute the standard deviation and variance ?
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78

#include <iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
#include<cmath>
using namespace std;
// Program reads input from a file with numbers of type double
// sums them up, computes and displays their average and standard deviation
// on the screen and output file
int main()
{
    ifstream fin;
    fin.open("inputData.txt");
    if (fin.fail())
    {
        cout<<" Error in creating input file...! "<<endl;
        exit(1);

    }
    else
    {
        cout<<" Opening Input file...."<<endl;
        cout<<" Reading Input Data from file...please wait "<<endl;

    }

    ofstream fout;
    fout.open("outputData.txt", ios::app);
    if (fout.fail())
    {
        cout<<" Error in creating output file .... !"<<endl;
        exit(1);
    }
    else
    {
        cout<<" Opening Output file ...."<<endl;
        fout<<" Reading Input Data from file...please wait"<<endl;
    }

    double next = 0, sum = 0, avg = 0, stdDev = 0,  variance = 0 ;
    int count = 0 ;
    cout.setf(ios::fixed);
    cout.setf(ios::showpoint);
    cout.precision(2);

    while(fin >> next)
    {
        fout.setf(ios::fixed);
        fout.setf(ios::showpoint);
        fout.precision(2);
        fout<<setw(6)<<next<<endl;
        sum = sum + next;
        count ++;
        avg =  sum / count ;

    }
    fin.clear();         // clear eof flag
    fin.seekg(0);         // go to the beginning of the file

    while (fin >> next )
    {
        fout.setf(ios::fixed);
        fout.setf(ios::showpoint);
        fout.precision(2);

        variance = (pow((avg - next),2));
        stdDev = sqrt(variance);
        cout<<setw(6)<<" There are "<<count<<" numbers whose sum is "<<sum<<" average is "<<setw(2)<<avg<<" variance is "<<variance<<" and standard deviation is "<<setw(2)<<stdDev<<endl;
        //fout<<setw(6)<<" There are "<<count<<" numbers whose sum is "<<sum<<" average is "<<setw(2)<<avg<<" variance is "<<variance<<" and standard deviation is "<<setw(2)<<stdDev<<endl;
    }
    fin.close();
    fout.close();

    return 0;

}
Here is some Pseudo code that may help.

1
2
3
4
5
Step 1: Find the mean.
Step 2: For each data point, find the square of its distance to the mean.
Step 3: Sum the values from Step 2.
Step 4: Divide by the number of data points.
Step 5: Take the square root.


It looks like you have completed steps 1 and 2. Looks like you need to do Step 3 inside the loop, steps 4 and 5 should be done after the loop.


For the second time:
Actually, line 29 [that computes the average] can go after the loop:

I even included code showing exactly how to do this.

And I repeated the idea again:
Line 35: Why do you compute the average after reading each number? You should wait until after the loop, just like I showed.


And for the third time:
Re-read the formulas for these values: your code doesn't compute them correctly and you'll need to fix that.

Ooops ...i have taken note of the average outside the loop and thats done now

its the last part you mention , i need help " Re-reading the formulas for the values " to calculate the variance i use the square of the number which is (Average - Number)*(Average - Number) i then use the function pow((average-number),2) . If i get your confirmation or help on this the sqrt(variance) should be working fine.
From www.mathsisfun.com/data/standard-deviation.html (emphasis added):
To calculate the variance follow these steps:
- Work out the Mean (the simple average of the numbers)
- Then for each number: subtract the Mean and square the result (the squared difference).
- Then work out the average of those squared differences. (Why Square?)

You aren't doing this last part.
Topic archived. No new replies allowed.