0

`

void avgOfArray()
{
    float avg = 0, *ptr = 0;
    ptr = (float*)malloc(5*sizeof(float));
    printf("Enter 5 numbers: \n");
    for(int x = 0; x < 5; x++) {
        ptr[x] = getchar();
        while ((ptr[x] = getchar()) != EOF && ptr[x] != '\n');
    }
    for (int y = 0; y < 5;  y++) {
        avg = avg + ptr[y];
    }
    avg = avg / 5;
    printf("Average = %0.2f \n", avg);
    system("pause");
}

`

I'm learning about pointers in class and the question asked to get the average of 5 numbers. Every output is 10 regardless of the input. If someone could explain the issue that would be very appreciated.

  • You've allocated `ptr` as a pointer to `float`, so you don't want to be doing a `getchar()` into `ptr[x]`. `getchar()` returns the ASCII value of an input character as an integer. If you're trying to read floats in from the user, you need to use something like `fgets` then parse using `sscanf` or `atof`. Also [do not cast the return of `malloc`](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). Just write `ptr = malloc(5 * sizeof(float));`. – lurker Feb 26 '18 at 01:48

2 Answers2

1

getchar returns the code of the character, not the float itself.

Since your loop scans the chars until it meets \n (ASCII code = 10), you always get 10 (as float).

Don't rewrite float scan, use fgets to get a line (issue with end of file or \n automatically handled), then scan 5 floats from the line buffer, or use scanf 5 times with a space

int i;
for (i=0;i<5;i++)
{
   scanf(" %f",p+i);  // no error check!
}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

Don't cast malloc, and also check the return value of malloc, if it returns NULL, you cannot access the memory otherwise it's undefined behaviour.

float *ptr = malloc(5 * sizeof *ptr);
if(ptr == NULL)
{
    fprintf(stderr, "Not enough memory\n");
    return; // or exit or whatever
}

Also note that dynamically allocating space is usually needed when the size is not known at compile time, because the user inputs the size or it has to be calculated. In your example you already know the size, malloc is not needed. float arr[5]; would be enough.

getchar(); returns a single character. The value of the character is determined by the ASCII table. The value for '1' is not the same as the value 1, because '1' is 49. You have to read all the characters forming a number and then convert them to float using functions like scanf or strtof.

Alternative 1: using scanf.

// assuming you are using ptr = malloc(...)
for(size_t i =  0; i < 5; ++i)
{
    while(scanf("%f", ptr + i) != 1)
    {
        // clear buffer
        int c;
        while((c = getchar()) != '\n' && c!= EOF));
        if(c == EOF)
        {
            // cannot continue doing scanf
            free(ptr);
            return; // or exit
        }
        printf("Please re-enter the number:\n");
    }
}

Alternative 2: using fgets

char line[50];
for(size_t i = 0; i < 5; ++i)
{
    while(1) // continue reading if value is not a float
    {
        if(fgets(line, sizeof line, stdin) == NULL)
        {
            // cannot continue reading
            free(ptr);
            return; // or exit
        }

        char *end;
        float val = strtof(line, &end);
        if(*end == '\n' || *end == '\0')
        {
            ptr[i] = val;
            break; // exit while(1) loop, continue reading next value
        } else
            printf("Please re-enter the number:\n");
    }
}

Also at the end do not forget to free the memory with free(ptr);.

Pablo
  • 13,271
  • 4
  • 39
  • 59