statistics program pulled from .txt file

Hey every body once again here for some help, not as much as help as before, lol and thanks again for help last time it really taught me a lot...

I have written a program that computes the mean and standard deviation of a data set collected from a .txt file. Its supposed to output the Mean of data, standard deviation (if 30 or more data points) or sample standard deviation (if fewer than 30 data points) of data. I thought I had it pretty good, It finds the file appears to read the file. knows when it has 30< or 30> but doesn't give me the correct numbers. I have been starring at this program and cant for the life of me see what is wrong with it. It also crashes now, smh. I now its a small thing that my eyes for some reason is not picking up. A point in the right direction would be greatly appreciated.

here is the program:



#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define file_name "my_data.txt"


/************************** MESSAGE FUNCTION ****************************/
void
msg1(void)
{

printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" );
printf("\n EE 150 \n" );
printf("\n Here you should put a message that the user");
printf("\n can read to know what the program is about" );
printf("\n and what to do to use it. \n\n\n\n\n\n\n\n" );

}

/* SOMETIMES YOU WILL PUT OTHER FUNCTIONS HERE */

/*************************** MAIN FUNCTION *******************************/


int
main(void)
{

/********************* DECLARATION OF VARIABLES **************************/
double num=0, sum=0, mean, sdev;
int SIZE, k, n, num_data_pts;
FILE *sensor;
sensor=fopen (file_name,"r");
/*******************THE EXECUTABLE PART OF THE PROGRAM ********************/

/******* Print the Opening Message *******/

msg1();

/******* Computate ************/



if (sensor==NULL)

printf("Error opening input file\n\n");

num_data_pts = fscanf(sensor, "%d", &num_data_pts);

for (k=1; k<=num_data_pts; k++)

{
fscanf(sensor,"%lf", &num);
printf("entered number %d is %lf\n",n , num);

sum +=num;
mean = sum/num_data_pts;

printf("\n The mean of the data set is %lf", mean);

if(num_data_pts >=30)
{
while (n != num_data_pts )
{

n = n+1;
sum = ((num-mean)*(num-mean)+sum);
sdev = sqrt(sum/num_data_pts);

printf("\n population standard deviation was used. \n\n");
printf("\n\n\n****The sdev of the data set is %lf****\n\n", sdev);
}
}
else
{
while (n != num_data_pts )
{

n = n+1;
sum = ((num-mean)*(num-mean)+sum);
sdev = sqrt(sum/(num_data_pts-1));

printf("\n Sample standard deviation was used. \n\n");
printf("\n\n\n****The sdev of the data set is %lf %s****\n\n", sdev);
}

}
}
return 0;
There has to be some body. : )
OK - I'll get the ball rolling..

This starts to go wrong almost from the start unfortunately:

1
2
3
4
5
6
7
8
 if (sensor==NULL)

        printf("Error opening input file\n\n");//fair enough but maybe you should also exit if the file load fails?? 

//The next line is a major error.
//You read the number of data points into the num_data_pts variable
//then you overwrite it with the return value of the fscanf function    
num_data_pts = fscanf(sensor, "%d", &num_data_pts); //ERROR!! 


That line should just be:

fscanf(sensor, "%d", &num_data_pts);
Last edited on
Thanks for the reply and the info. I made the corrections suggested by guestgulkan. this is what it looks like now.

[code]if (sensor==NULL)
{
printf("Error opening input file\n\n");
} {code]
fscanf(sensor, "%d", &num_data_pts);



I actually argued about the num_data_pts = fscanf to. I lost the arguement do to my noobness. thanks for the fix. Also it does make sense now to exit the program. after finding the error. thanks for that also.

still no changes, program still acts the same. its seems to be reading from a ghost txt file. cause I actually put 5 data points. 1,2,3,4,5 . and its not reading it and keeps giving me 2.0 for an answer.

any other suggestions would be greatly appreciated.
Last edited on
Please use code tags: [code]Your code[/code]
See: http://www.cplusplus.com/articles/z13hAqkS/

This while (n != num_data_pts ) is within the for (k=1; k<=num_data_pts; k++) loop. they run just once when k is 1. I don't see the use of it
@OP

Just so you know about fscanf - read this:

http://www.cplusplus.com/reference/clibrary/cstdio/fscanf/


fscanf returns an int which is the number of items filled. You can use this to do some error checking.

If the value return is zero then the fscanf failed. You can also check to see if only some of the items were filled.

Unfortunately the example doesn't show it, but it does mention it under the return value heading.

Edit: My general comment is that you should read up about all the functions you use, so that you understand how they work. The reference section on this site is a really good resource - you can get at it from the link at the top left of this page.

Oh, and my omnipresent request for code tags
Last edited on
Made some adjustments. removed the k<= num_data_pts from the for loop. also added code tags. Now reading reference for fscanf. from reading the reference for fscanf it reads the info from the stream or data you told it to read and stores its weighting for you to tell it what to do with it.



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
int
main(void)
{

/********************* DECLARATION OF VARIABLES **************************/
double num=0, sum=0, mean, sdev;
int SIZE, k, n, num_data_pts;
FILE *sensor;
sensor=fopen (file_name,"r");
/*******************THE EXECUTABLE PART OF THE PROGRAM ********************/

/******* Print the Opening Message *******/

msg1();

/******* Computate ************/ 



if (sensor==NULL)

printf("Error opening input file\n\n");

 fscanf(sensor, "%d", &num_data_pts); 

for (k=1;k++;)/*this is supposed to be for the mean*/

{ 
fscanf(sensor,"%lf", &num); /*is this not proper usage for it, if not how should i use it? */
printf("entered number %d is %lf\n",n , num);

sum +=num;
mean = sum/num_data_pts;

printf("\n The mean of the data set is %lf", mean); 

if(num_data_pts >=30)/*population strd deviation*/
{
while (n != num_data_pts )
{
 
n = n+1; 
sum = ((num-mean)*(num-mean)+sum);
sdev = sqrt(sum/num_data_pts); 

printf("\n population standard deviation was used. \n\n");
printf("\n\n\n****The sdev of the data set is %lf****\n\n", sdev);
}
}
else
{
while (n != num_data_pts ) /* sample strd deviation*/
{

n = n+1;
sum = ((num-mean)*(num-mean)+sum);
sdev = sqrt(sum/(num_data_pts-1)); 

printf("\n Sample standard deviation was used. \n\n"); 
printf("\n\n\n****The sdev of the data set is %lf %s****\n\n", sdev);
}

} 
} 
return 0; 
Last edited on
I meant to make use of the return value for fscanf, to do error checking like this:


1
2
3
4
5
6
7
int CheckFscan;  /* Check the value return by fscanf */

CheckFscan =fscanf(sensor,"%lf", &num);
if(CheckFscan != 1) {
/* do error processing */
}


It is an important idea in programming, to be always try to think of what might go wrong, and to do tests to see whether they have gone wrong so you can do something about it. This is much better than the code failing, which is what you are trying avoid wherever possible.

Another thing, even though it is only a few lines of code, I would have had functions to work out the 2 different std deviations. This would make the code a little clearer:


1
2
3
4
5
if(num_data_pts >=30)/*population strd deviation*/
   PopStdDev(); /* You figure out the args needed */
else
    SampStdDev();


You would need to declare these functions before main.

Did you forget to include stdio.h ?

Anyway good luck with your C Programming - Hope all goes well.

If you have any further problems, post the compiler output.
Actually, there is only one line that is different between the 2 functions, so you could have 1 simple function, with an if at the end to decide which std dev to calc.

You should always try to avoid duplicating code, it sometimes means putting code into functions, but in this case it is solved by a simple if statement.
Last edited on
thank you very much for the replies. let me soak all this in then i will get back tomorrow with what I have.
had to re-think my program and using some of the ideas from above statements and suggestions came up with this. it works perfectly. here is the code what do you guys think.

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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define file_name "my_data.txt"


/**************************  MESSAGE FUNCTION  ****************************/
void
msg1(void)
{
          
	printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" );
	printf("\n    The function of this program is to compute\n" );    
    printf("\n    the mean and standard deviation of a data set.\n");                        
    printf("\n    Data file [not taken from keyboard], upper   \n"); 
    printf("\n    bound, lower bound. Mean of data, standard   \n");
    printf("\n    deviation (if 30 or more data points)         \n"); 
    printf("\n    or sample standard deviation (if fewer than 30)\n ");
    printf("\n    data points.  \n\n\n\n\n\n\n\n                  ");

}

            /* SOMETIMES YOU WILL PUT OTHER FUNCTIONS HERE */

/***************************  MAIN FUNCTION  *******************************/


int
main(void)
{

/********************* DECLARATION OF VARIABLES **************************/
double sum=0, mean, sdev, loop=1,values[1000],count=(0),upper,lower;
double limitu,limitl,lim=0, std=0,input;
double dat=0;
int SIZE, k, n, x=0;
FILE *data;
data=fopen (file_name,"r");
char unit,u,ans='Y';
/*******************THE EXECUTABLE PART OF THE PROGRAM ********************/

/******* Print the Opening Message *******/

msg1();

/******* Computate ************/ 


while(ans=='Y' || ans=='y')
{
               
    if(data==NULL)
    {
                  
                   printf("Error opening file.\n\n");
    }
    
    
         else
           {
                   
while((fscanf(data,"%lf",&values[x]))==1)
        {
                            input=values[x];
                            x++;
                            sum=sum+input;
                            count++;
                            loop++;
           }
        }
    
                   printf("\n Please enter your upper bound.\n\n");
                   scanf("%lf",&upper);
    
                   printf("\n Please enter your lower bound.\n\n");
                   scanf("%lf",&lower);


/*mean*/
                            loop--;
                            x=0;
                            mean=(sum/loop);
                            
                            
                   printf("\n You have a total of %0.0f inputs.\n\n",loop);
                   
                   printf("\n Your mean value is %0.3f in %c units.\n\n",mean,unit,u);

/** Standard Deviation Calculations **/

    if (count>=30)
       {
while (count>x)
      {
                           std=std+(values[x]-mean)*(values[x]-mean);
                           x++;
       }
                           std=sqrt(std/count);
                           
                           
                  printf("\nStandard Deviation equals +/- %f.\n\n",std,unit,u);
      }

/** Sample Standard Deviation Calculations **/    
    if (count<30)
    {
while (count>x)
      {
                          std=std+(values[x]-mean)*(values[x]-mean);
                          x++;
      }
                          std=sqrt(std/(count-1));
                          
                          
                  printf("\nThe Sample Standard Deviation equals %f.\n\n",std,unit,u);      
    }
    
                          limitu=mean+3*std;
                          limitl=mean-3*std;
    
    if(limitu>upper)
    {
                   printf("\nThe upper bound is exceeded.\n\n");
                   lim++;
    }
    
    if(limitl<lower)
    {
                   printf("\nThe lower bound is exceeded.\n\n");
                   lim++;
                   
    }


    if(lim==0)
    {
                   printf("\nThe data fits within the bounds.\n\n");
    }
                   printf("\nWould you like to perform another calculation with new bounds? (Y/N)\n\n");
                   
                   printf("\nNote: Any input other than 'Y' or 'y' will end the program.\n\n");
                   scanf("%c %c",&ans,&ans);
}

                   
	return 0;

}


You still have two while loops that are almost identical.

TheIdeasMan wrote:
Actually, there is only one line that is different between the 2 functions, so you could have 1 simple function, with an if at the end to decide which std dev to calc.


These two lines are the same for each calculation:

1
2
std=std+(values[x]-mean)*(values[x]-mean);
                           x++;


So then you need an if statement to decide which of these to do:

std=sqrt(std/count);

or

std=sqrt(std/(count-1));

and this line is the same:

printf("\nThe Sample Standard Deviation equals %f.\n\n",std,unit,u);

Can you figure out how to do this?

As I said earlier, you should look for code that is the same, and think of a way to avoid it.
I would like to be able to do that. it would definitely shorten the program. How would i put the two together cause i cant figure out how. I have always used 2 while loops and even 3 sometimes.
Well, I spelled it out in my last post - give it a try.
sure will i will get back..
Topic archived. No new replies allowed.