M.Stadnicki
M.Stadnicki

Reputation: 13

Having Trouble Calculating The Correct Average of 10 Integer Values in C

Hello Stack Community!

I am having trouble calculating the correct average for 10 integers. The expected output average is supposed to be 140.0 with one integer value recognized as not a positive program by the compiler.

This is what I have compiled, and it recognized the negative integer but the average still comes to 150.0

Just trying to figure out what I am missing here. Thanks!

#include <stdio.h>
int main ()
{
    /* variable definition: */
    int count, value, sum;
    double avg;
    /* Initialize */
    count = 0;
    sum = 0;
    avg = 0.0;
    // Loop through to input values
    while (count < 10)
    {
        printf("Enter a positive Integer\n");
        scanf("%d", &value);
        if (value >= 0) {
            sum = sum + value;
            count = count + 1;
        }
        else {
            printf("Value must be positive\n");
        }
    }
     // Calculate avg. Need to type cast since two integers will yield an integer
    avg = (double) sum/count;
    printf("average is %lf\n " , avg );
    return 0;
}

Values are: 100 100 100 100 -100 100 200 200 200 200

Upvotes: 1

Views: 802

Answers (5)

chqrlie
chqrlie

Reputation: 144969

AlexP found the explanation: you must check the return value of scanf(), otherwise, you will silently accept input that is not a number and reuse the last converted value.

Also note that the cast in avg = (double) sum/count; applies to sum and binds stronger than /. It is considered good style to make this more explicit by writing avg = (double)sum / count;

Here is a modified version of your program:

#include <stdio.h>

int main(void) {
    /* variable definitions */
    int count, value, sum;
    double avg;

    /* Initializations */
    count = 0;
    sum = 0;
    avg = 0.0;

    // Loop through to input values
    while (count < 10) {
        printf("Enter a positive Integer\n");
        if (scanf("%d", &value) != 1) {
            break;
        }
        if (value >= 0) {
            sum = sum + value;
            count = count + 1;
        } else {
            printf("Value must be positive\n");
        }
    }
    // Calculate avg.
    // Need to type cast to force floating point division instead of integer division
    if (count > 0) {
        avg = (double)sum / count;
        printf("average is %f\n", avg);
    }
    return 0;
}

Upvotes: 0

user7015283
user7015283

Reputation:

while (count < 10) { 
    printf("Enter a positive Integer\n"); 
    scanf("%d", &value);
    if (value >= 0) { 
        sum += value;
        count++; 
    }
    else {
        printf("Value must be positive\n"); 
        count++;
    }
}

This will increment "count" even if negative integer is inputted. Thus you will get the desired average.

Upvotes: 0

David C. Rankin
David C. Rankin

Reputation: 84579

There are a number of different ways to approach the problem. (1) you can read your values as a string with fgets and then call sscanf and gain the benefit of a NULL return from fgets indicating EOF and a test of the buffer containing only '\n' to indicate a user pressed [Enter] to signal end of input.

(2) you can read the values numerically with scanf and then check for EOF to indicate end of input, or some other predetermined sentinel.

Regardless of which you choose, the approach is basically the same. (a) make a call to the function you are using for input, (b) check the RETURN, and (c) validate the value input is within the required range, and handle the data.

You get the drift, on all input, check the return of your read function and handle any error or EOF condition, then validate the input is within the expected range.

A quick example using your code and reading numeric values with scanf could be something like:

#include <stdio.h>

int main (void) {

    /* define/initialize variables */
    int count = 0, value = 0, sum = 0;
    double avg = 0.0;

    while (1) {  /* infinite loop to process input */

        int rtn;
        printf ("Enter a positive Integer ([ctrl+d] to quit): ");

        if ((rtn = scanf ("%d", &value)) != 1) {
            if (rtn == EOF) {   /* always handle user cancellation of input */
                putchar ('\n'); /* tidy up with POSIX line ending */
                break;          /* on to final calculation */
            }
        }

        if (value < 0)  /* check out of range */{
            printf ("Value must be positive\n");
            continue;       /* try again */
        }

        sum = sum + value;  /* compute sum */
        count = count + 1;  /* increment count */
    }

    /* Calculate avg. (typecast to avoid integer division) */
    avg = count > 0 ? (double) sum/count : 0;  /* protect div by zero */
    printf ("\n (%d/%d) => average: %lf\n", sum, count, avg);

    return 0;
}

Example Use/Output

$ ./bin/sumavg < <(echo "100 100 100 100 -100 100 200 200 200 200")
Enter a positive Integer ([ctrl+d] to quit):
<snip>

 (1300/9) => average: 144.444444

One common thread running between all complete examples is to always handle a manual EOF generated by the user allowing them to cancel an individual input, or input as a whole (you decide based on your needs). On Linux the manual EOF is generated by [ctrl+d] on windoze [ctrl+z].

Look all answers over and let me know if you have any questions related to the above.

Upvotes: 0

Rishi
Rishi

Reputation: 1395

If I understand your problem correctly, this is what you want to do :

int last_known_positive_value = 0;
// Loop through to input values
while (count < 10)
{
    printf("Enter a positive Integer\n");
    scanf("%d", &value);

    if (value >= 0) {
        sum = sum + value;
        last_known_positive_value = value;
    }
    else {
        printf("Value must be positive\n");
        sum = sum + last_known_positive_value;
    }
    count = count + 1;
}

check-answer-here

Upvotes: 0

AlexP
AlexP

Reputation: 4430

  1. You want to read exactly 10 positive numbers, with count from 0 to 9.

  2. After reading 100 100 100 100 -100 100 200 200 200 200 the value of count is 9 (because -100 neither added to the sum nor counted), which is less that 10 so the loop is executed one more time.

  3. This time scanf() fails, so value remains unchanged; effectively you are reading another 200.

  4. This is why the sum of the numbers is 1500 and the average 150.

Upvotes: 1

Related Questions