Reputation: 55
I am attempting to write a program that takes a user's inputted text file and returns the largest number, smallest number, average of the numbers and the standard deviation of the numbers. The text file that we input is formatted as such (with the first number being "N", or the total number of numbers, and the second row the list of all the numbers):
5
4.34 23.4 18.92 -78.3 17.9
So far, this is my code
int main(int argc, char*argv[])
{
double average, num = 0, min = 0, max = 0, sum = 0, N, std_dev, sum_sqs;
FILE * pFile;
pFile = fopen("argv[1]", "r");
fscanf(pFile, "%lf", &N);
while(!feof(pFile))
{
fscanf(pFile, "%d", &num);
if (num < min)
min = num;
if (num > max)
max = num;
sum += num;
sum_sqs += (num*num);
}
average = sum/N;
std_dev = sqrt((sum_sqs/N)-(average*average));
printf("Smallest: %.2lf\n", min);
printf("Largest: %.2lf\n", max);
printf("Average: %.2lf\n)", average);
printf("Standard deviation: %.3lf\n", std_dev);
return(0);
}
Currently, the compiler does not let me get past an error about an undefined reference to sqrt and i cannot figure out what's wrong. Thank you in advance to everybody who takes the time to respond! I really appreciate any help, I am still getting the hang of C. If my code is not doing what I intend it to do please dont hesitate to correct me!
Updated the messy part to below. Still not sure what exactly im doing with the rest though haha pFile = fopen(argv[1], "r"); fscanf(pFile, "%lf", &N);
if (fscanf(pFile, "%lf", &N) == 1)
{
for (int i = 0; i < N; i++)
{
if (fscanf(pFile, "%lf", &num) == 1)
if (num < min)
min = num;
if (num > max)
max = num;
sum += num;
sum_sqs += (num*num);
}
average = sum/N;
std_dev = sqrt((sum_sqs/N)-(average*average));
Upvotes: 0
Views: 12323
Reputation: 753525
There is a wealth of problems in these few lines:
pFile = fopen("argv[1]", "r");
fscanf(pFile, "%lf", &N);
while(!feof(pFile))
{
fscanf(pFile, "%d", &num);
argv[1]
, not a file called argv[1]
. Remove the quotes.fopen()
succeeded, so you probably crashed in your first fscanf()
.fscanf()
succeeded. It is also odd to read what should probably be an integer value into a double
, but the notation used will work.feof()
like that, especially if …fscanf()
succeeded, and it won't work properly (but might not report the problem) because …%d
) into a double
.So, you should have written:
if (argc <= 1)
…report error and exit…(or use pFile = stdin)…
FILE *pFile = fopen(argv[1], "r");
if (pFile == 0)
…report error and exit…
if (fscanf(pFile, "%lf", &N) == 1)
{
for (int i = 0; i < N; i++)
{
if (fscanf(pFile, "%lF", &num) != 1)
…report error, close file, and exit…
…as before…more or less…subject to fixing any as yet undiagnosed errors…
}
}
fclose(pFile);
Incidentally, you forgot to set sum_sqs
to zero before you started adding to it, so you won't know what value you got. Also, if all the numbers are negative, you'll report that the maximum is 0; if all the numbers are positive, you'll report that the minimum is 0. Fixing that is a tad fiddly, but you could use if (i == 0 || num < min) min = num;
etc.
Your linking problem (undefined reference to sqrt()
) indicates that you are running on a system where you need to link the maths library; that is usually -lm
on the end of the linking command line.
#include <stdio.h>
#include <math.h>
int main(int argc, char*argv[])
{
double average, num = 0, min = 0, max = 0, sum = 0, N, std_dev, sum_sqs = 0.0;
if (argc <= 1)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 1;
}
FILE *pFile = fopen(argv[1], "r");
if (pFile == 0)
{
fprintf(stderr, "%s: failed to open file %s\n", argv[0], argv[1]);
return 1;
}
if (fscanf(pFile, "%lf", &N) == 1)
{
for (int i = 0; i < N; i++)
{
if (fscanf(pFile, "%lF", &num) != 1)
{
fprintf(stderr, "%s: failed to read number\n", argv[0]);
return 1;
}
if (num < min || i == 0)
min = num;
if (num > max || i == 0)
max = num;
sum += num;
sum_sqs += (num*num);
}
}
fclose(pFile);
average = sum/N;
std_dev = sqrt((sum_sqs/N)-(average*average));
printf("Smallest: %7.2lf\n", min);
printf("Largest: %7.2lf\n", max);
printf("Average: %7.2lf\n", average);
printf("Standard deviation: %7.3lf\n", std_dev);
return(0);
}
Given data file data
:
5
4.34 23.4 18.92 -78.3 17.9
The result of running the program is:
Smallest: -78.30
Largest: 23.40
Average: -2.75
Standard deviation: 38.309
Those values mostly look plausible; my calculation of the standard deviation came to 42.83 (using a different tool altogether). The difference is between the sample standard deviation and the population standard deviation (a factor of √1.25) — so your value is OK as you calculated it.
# Count = 5
# Sum(x1) = -1.374000e+01
# Sum(x2) = 7.375662e+03
# Mean = -2.748000e+00
# Std Dev = 4.283078e+01
# Variance = 1.834476e+03
# Min = -7.830000e+01
# Max = 2.340000e+01
So, the code works for me. What result are you getting?
Upvotes: 6
Reputation: 8492
If you want the sqrt
function, you need to add
#include <math.h>
to the top of your C file.
float
with scanf
, you should be using the %f
format specifier, not %d
(which will read an integer).fopen
call, remove the quotes around argv[1]
, otherwise it'll look for a file with that name.Upvotes: 0