Вопрос

I have a program which reads floating point numbers from a .txt file and puts them into an array but I have a problem with calculating median. Everything is working perfectly except from this. What am I doing wrong?

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


int compare (const void * a, const void * b)
{
  float fa = *(float*) a;
  float fb = *(float*) b;
  return (fa > fb) - (fa < fb);
}



//median calculations//
float median1(float[],int); 
float median1(float array[],int n) 
{  
qsort(array, n, sizeof(float), compare);

if(n%2==0)  
    return (array[n/2]+array[n/2-1])/2;  
else  
    return array[n/2];  
}



float x,l=~(257<<23),a,s,t,median;
main(int n,char**f)

{
char fname[20];
int i;
a=-l;

printf("Please type the file name with an extension (.txt)\n");
scanf("%s", fname);


f=fopen(fname,"r");
for(n=0;fscanf(f,"%f",&x)>0;n++,s+=x,x<l?l=x:0,x>a?a=x:0,t+=x*x);

float array[n];

fseek (f, 0, SEEK_SET);

for (i=0; i<n; i++) 
        {
            fscanf (f, "%f", &(array[n]));
        }

median=median1(array,n);  

printf("Sample size = %d\n", n);
printf("Minimum = %f\n", l);
printf("Maximum = %f\n", a);
printf("Mean = %f\n", s/n);
printf("Median = %f\n",median);
printf("Standard deviation = %f\n", sqrtf(t/n));

return 0;
} 
Это было полезно?

Решение

fscanf (f, "%f", &(array[n]));

should be

fscanf (f, "%f", &(array[i]));

You are only writing to one array element and that one is out-of-bound.

Even if this wouldn't result in undefined behavior, you would still work with garbage values later on.

See @JonathanLeffler's comment for some further remarks on your code.

Другие советы

This is a cleaned up version of your code…but select Nabla's answer.

It compiles cleanly with:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Werror med.c -o med

It shows that you were not dreadfully far off. I have not fixed the initializer for l. I did ensure that s and t are both zeroed before you start accumulating values in them. The code does not check that fscanf() works on the second pass. I've not fixed it to read from standard input or to take the file name from its arguments, either of which would make it a lot more usable.

Given input data:

1.2
3.5
2.9
4.6

it produces the output:

Sample size = 4
Minimum = 1.200000
Maximum = 4.600000
Mean = 3.050000
Median = 3.200000
Standard deviation = 3.288617

Semi-fixed code

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int compare(const void *a, const void *b);

int compare(const void *a, const void *b)
{
    float fa = *(float *) a;
    float fb = *(float *) b;
    return (fa > fb) - (fa < fb);
}

// median calculations//
float median1(float[], int);

float median1(float array[], int n)
{
    qsort(array, n, sizeof(float), compare);

    if (n % 2 == 0)
        return (array[n / 2] + array[n / 2 - 1]) / 2;
    else
        return array[n / 2];
}

int main(void)
{
    float x;
    float l = ~(257 << 23);
    float a;
    float s = 0.0;
    float t = 0.0;
    float median;
    int n;
    FILE *f;
    char fname[20];
    int i;
    a = -l;

    printf("Please type the file name with an extension (.txt)\n");
    scanf("%s", fname);


    f = fopen(fname, "r");
    if (f == 0)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", fname);
        return 1;
    }

    for (n = 0; fscanf(f, "%f", &x) > 0; n++)
    {
        s += x;
        if (x<l) l = x;
        if (x>a) a = x;
        t += x * x;
    }

    float array[n];

    fseek(f, 0, SEEK_SET);

    for (i = 0; i < n; i++)
    {
        fscanf(f, "%f", &(array[i]));
    }

    fclose(f);

    median = median1(array, n);

    printf("Sample size = %d\n", n);
    printf("Minimum = %f\n", l);
    printf("Maximum = %f\n", a);
    printf("Mean = %f\n", s / n);
    printf("Median = %f\n", median);
    printf("Standard deviation = %f\n", sqrtf(t / n));

    return 0;
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top