Reputation: 13
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
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
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
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
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;
}
Upvotes: 0
Reputation: 4430
You want to read exactly 10 positive numbers, with count
from 0
to 9
.
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.
This time scanf()
fails, so value
remains unchanged; effectively you are reading another 200
.
This is why the sum of the numbers is 1500
and the average 150
.
Upvotes: 1