Program to compute the average of values: if to test chars - c

Please, take a look at a program that prompts the user to enter 3 values and computes the average of these values.
I decided to add a test condition that checks if the user has entered a number or a character.
// a program that calculates the average of an array of 3 floating-point values; with for loop
#include <stdio.h>
int main (void)
{
float values[3];
float element;
float sum = 0;
int i;
printf ("Please, enter 3 floating values: \n");
for ( i = 0; i < 3; i++)
{
if (scanf ("%f", &element) == 1)
{
if ( (element >= 'a' && element <= 'z') || (element >= 'A' && element <= 'Z') )
printf ("Sorry, you have entered letters\n");
else if (element <= 0)
printf ("Please, enter positive values\n");
else
values[i] = element;
sum += values[i];
}
}
printf ("The average of 3 values is %.2f\n", sum / 3);
return 0;
}
When I run the program, I get the following problems:
1) it seem to work with positive numbers;
2) when I try to enter negative numbers, the program does print the required statement, but the result is still incremented into i, hence lowering the number of further entries; also, even if the number is negative, the program still comes up with some average nonsense value.
Please, enter 3 floating values:
-75
Please, enter positive values
98
Sorry, you have entered letters
-786.9
Please, enter positive values
The average of 3 values is 2087205705198174400484999168
3) when I test the program with letters, it still returns some average, though a zero one:
Please, enter 3 floating values:
jklj
The average of 3 values is 0.00
I would be grateful for your help!

Your element will never contain letters, since you've declared it as float and scanned it as float. If you wish to know if you were given a letters, you should read a string, test it, and only then convert it to float (comparing element to 'a' is actually comapring it to the ASCII code of 'a' = 97).
About the wrong sum - you forgot the curly braces for your else block. Change it to:
else {
values[i] = element;
sum += values[i];
}

If you want your program to end if negative numbers are entered you can use the return statement or deincrement the value of i for more cases. As for letter it never enters the if block so you can use an else. Try the following:
#include <stdio.h>
int main (void)
{
float values[3];
float element;
float sum = 0;
int i;
printf ("Please, enter 3 floating values: \n");
for ( i = 0; i < 3; i++)
{
if (scanf ("%f", &element) == 1)
{
if (element <= 0)
{
printf ("Please, enter positive values\n");
i--; // or use the return statement
}
else
{
values[i] = element;
sum += values[i];
}
}
else
{
printf("You entered special characters");
return;
}
}
printf ("The average of 3 values is %.2f\n", sum / 3);
return 0;
}

Related

(Visual Studio)Calculation _using for sentence

Want to elicit average of entered real value,until negative value is entered.
My problem is
My calculation don't quit when negative value is entered
It keep asks printf sentence for 3 time.
What did I do wrong?
#include <stdio.h>
int main(void)
{
double total = 0.0;
double input=0.0;
int num = 0;
for (; input >= 0.0;)
{
total += input;
printf("real number(minus to quit):");
scanf_s("%1f", &input);
num++;
}
printf("average:%f \n", total / (num - 1));
return 0;
}
you have many problems with your code :
it's not %1f in the line scanf_s("%1f", &total); as %1f will give you undefined behavior , it's %lfas you are scanning a double , there is a big difference between number one and lower case L
the function called scanf returns an integer indicating how many elements could be assigned to the input that the user entered , so , you should do if(scanf_s("%lf", &input) == 1) to check if the assignment done successfully, that will help you in detecting if - is entered instead of the number
if the user entered a lonely - then sacnf will fail to convert and you have to take another approach
when you are printing the average in this line : printf("average:%f \n", total / (num - 1)); , you actually prints a double , so it's %lf instead of %f
the condition of the for loop is incorrect , you are saying for (; input >= 0.0;) but this will prevent you from entering any negative values as when entering a negative value , the for loop will break , so you could use while(1) instead of the for loop and only break when a - is entered alone
so here is my edited version of yours , I introduced a dummy string to read the buffer and check whether the input was a lonely - or not , and if not then I try to convert it to double and here is my edited solution :
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char dummy[30];
double total = 0.0;
int num = 0;
double DecimalConverted = 0;
while(1)
{
printf("real number(minus to quit):");
fgets(dummy, 30, stdin); // gets the input into the buffer
if(dummy[0] == '-' && dummy[1] == '\n') // break from the loop on condition that '-' only entered
break;
// convert the string to decimal
DecimalConverted = strtod(dummy ,NULL);
if(DecimalConverted == 0)
printf("not a number\n");
else{
total += DecimalConverted;
num++;
}
}
printf("average:%lf \n", total / (num - 1));
return 0;
}
and here is the output :
real number(minus to quit):12
real number(minus to quit):-51
real number(minus to quit):-
average:-39.000000

Logic error when averaging several different numbers and outputting the result

I'm just beginning C, and I am encountering a logic error when trying to output the average of numbers entered. I will provide the source code of the program below.
// integer_sequence_avg.c
// Inputs a sequence of integers then averages them and outputs the result after the sentinel value "9999" is entered.
#include <stdio.h>
int main(void) {
// initializaiton
int addend = 0;
int sum = 0;
int average;
unsigned int counter;
for (addend; addend != 9999; ++counter) {
printf("%s", "Enter an integer to be averaged. Enter \"9999\" when you want to receive the average: "); // prompt to enter integers to be averaged
scanf("%d", &addend); // scans input into variable to be added to sum
if (addend != 9999) {
sum += addend; // Adds addend to sum
}
}
if (counter != 0) {
average = sum / counter; // Calculates average
printf("\nThe average of the integers added was %d\n\n", average); // Outputs average of numbers entered
} else {
printf("\nNo integers were entered.\n\n"); // Outputs that no integers were entered
}
system("pause");
return 0;
}
logic error screenshot
https://i.stack.imgur.com/Fwwaa.png
counter is incremented without being initialized. This invoked undefined behavior.
counter is incremented even when addend != 9999 is false.
Return values of scanf() should be checked to see if it successfully read things.
Instead of this
unsigned int counter;
for (addend; addend != 9999; ++counter) {
printf("%s", "Enter an integer to be averaged. Enter \"9999\" when you want to receive the average: "); // prompt to enter integers to be averaged
scanf("%d", &addend); // scans input into variable to be added to sum
if (addend != 9999) {
sum += addend; // Adds addend to sum
}
}
Try this:
unsigned int counter = 0;
while ( addend != 9999 ) {
printf("%s", "Enter an integer to be averaged. Enter \"9999\" when you want to receive the average: "); // prompt to enter integers to be averaged
if (scanf("%d", &addend) != 1) break; // scans input into variable to be added to sum
if (addend != 9999) {
sum += addend; // Adds addend to sum
++counter;
}
}
The problem is here:
for (addend; addend != 9999; ++counter) {
where counter is not initialized before using.
The fix: unsigned int counter = 0;
The only thing to address beyond that is that the counter value is being incremented once beyond what it should, giving wrong results.
eg, for these inputs:
4+6+8+9
Average should be 27/4 == 6, but counter == 5 after only 4 entries,
Average is computed as 27/5 == 5
To address this
change average = sum / counter;
to average = sum / (counter - 1);
Beyond that, integer division results in rounding, so unless the numerator contains all of the prime factors of the denominator, the result will invoke integer rounding. If that is a concern, floating point variables should be considered.

Calculating average of pair numbers

Hello I have been working on a program in C that calculates numbers and it gives me back an average. Now I'm having issues implementing code that will ask a user to enter any number of pairs and calculate the average. Below is the code that I been working on. I'm able to change the while (count < 5)to 10 to get more pairs, but my goal is to ask a user to input any PAIR and THEN calculate the average (re iterating).
#include <stdio.h>
int main () {
int count;
double avg, value, weight, sum, sumw;
count = 0;
sum = 0;
sumw = 0;
avg = 0.0;
while (count < 5) {
printf("Enter value and it's weight:");
scanf("%lf %lf", &value, &weight);
if (weight >= 0) {
sumw = sumw + weight;
sum = sum + value * weight;
count = count + 1;
}
else { printf("weight must be positive\n");
}
}
avg = sum / sumw;
printf("average is %lf\n " , avg );
return 0;
}
**Second part ** On this on I'm not too sure how to make it to PAIRS plus calculate avg. ej: 2 1 , 2 4 , 4 4 etc.
#include<stdio.h>
void main()
{
int i,n,Sum=0,numbers;
float Average;
printf("\nPlease Enter How many pairs do you want?\n");
scanf("%d",&n);
printf("\nPlease Enter the elements one by one\n");
for(i=0;i<n;++i)
{
scanf("%d",&numbers);
Sum = Sum +numbers;
}
Average = Sum/n;
printf("\nAverage of the %d Numbers = %.2f",n, Average);
return 0;
}
but my goal is to ask a user to input any PAIR and THEN calculate the
Well, then you need to store the values somewhere. Recommendation: Have a struct for:
typedef struct
{
double value;
double weight;
} Pair;
Then as soon as you have got number of pairs to read from user, create an array of pairs:
Pair* pairs = malloc(number * sizeof(*pairs));
Very important: Every malloc should go with a free to avoid memory leaks. General recommendation: plan the free immediately when or even before mallocing.
Now inside your loop, you can fill the pairs:
scanf("%lf %lf", &pairs[i].value, &pairs[weight].weight);
Analogously, you can then use the pairs in the array in next loop or for whatever other purpose.
Side note:
if (weight >= 0)
{
// ...
}
else
{
// printf("weight must be positive\n");
}
If user gave negative input, you'll be just skipping some values (or or as in loop proposed, still retain the negative values!).
You might instead read inside a nested loop until value is valid. Additionally consider user providing non-numeric input, too! In that case, you couldn't read a double at all. So general rule is: Always check the result of scanf:
if(scanf("%lf %lf", &value, &weight) != 2 || value < 0 || weight < 0)
// ^
// assuming negative value not desired either
{
// user input was invalid!!!
}

Why are my values for sum and count being lost each loop?

I'm getting a consistent divide by zero error, even though each loop should be populating the variables. Code below:
#include <stdio.h>
void calculateAverage()
{
int grade, count, sum;
double average;
sum = 0;
count = 0;
grade = 0;
average = 0.0;
int coolvalue = 0;
while (coolvalue==0)
{
scanf("%d", &grade);
if (grade == -1)
{
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
}
else
{
if ((grade > 100) || (grade < -1))
{
printf("Error, incorrect input.\n");
break;
}
else
{
sum = +grade;
count = count + 1;
return count;
return sum;
}
}
}
coolvalue = 1;
}
int main(void)
{
while (1)
calculateAverage();
while (1) getchar();
return 0;
}
Even while using return, I'm not able to properly increment the value of sum or count.
There are multiple issues in your code.
scanf("%d", &grade); - you don't check the value returned by scanf(). It returns the number of values successfully read. If you enter a string of letters instead of a number, scanf("%d") returns 0 and it does not change the value of grade. Because of this the code will execute the rest of the loop using the previous value of grade. You should restart the loop if the value returned by scanf() is not 1:
if (scanf("%d", &grade) != 1) {
continue;
}
Assuming you enter 10 for grade this block of code executes:
sum = +grade;
count = count + 1;
return count;
return sum;
sum = +grade is the same as sum = grade. The + sign in front of grade doesn't have any effect. It is just the same as 0 + grade.
You want to add the value of grade to sum and it should be sum += grade. This is a shortcut of sum = sum + grade.
return count makes the function complete and return the value of count (which is 1 at this point) to the caller. The caller is the function main() but it doesn't use the return value in any way. Even more, your function is declared as returning void (i.e. nothing) and this renders return count incorrect (and the compiler should warn you about this).
return sum is never executed (the compiler should warn you about it being dead code) because the function completes and the execution is passed back to the caller because of the return count statement above it.
Remove both return statements. They must not stay here.
If you enter -1 for grade, this block of code is executed:
sum, sizeof(double);
count, sizeof(double);
average = (sum / count);
printf("%lf", &average);
break;
sum, sizeof(double) is an expression that does not have any effect; it takes the value of sum then discards it then takes the value of sizeof(double) (which is a constant) and discards it too. The compiler does not even generate code for it.
the same as above for count, sizeof(double);
average = (sum / count);:
the parenthesis are useless;
because both sum and count are integers, sum / count is also an integer (the integral result of sum / count, the remainder is ignored).
you declared average as double; to get a double result you have to cast one of the values to double on the division: average = (double)sum / count;
if you enter -1 as the first value when the program starts, count is 0 when this code is executed and the division fails (division by zero).
printf("%lf", &average); - you want to print the value of average but you print its address in memory. Remove the & operator; it is required by scanf() (to know where to put the read values). It is not required by printf(); the compiler generates code that passes to printf() the values to print.
break; - it passes the execution control after the innermost switch or loop statement (do, while or for). It is correct here and makes the variable coolvalue useless. You can simply remove coolvalue and use while (1) instead.
All in all, your function should look like:
void calculateAverage()
{
int sum = 0;
int count = 0;
int grade = 0;
double average = 0.0;
while (1) {
if (scanf("%d", &grade) != 1) {
// Invalid value (not a number); ignore it
continue;
}
// A value of -1 signals the end of the input
if (grade == -1) {
if (count > 0) {
// Show the average
average = (double)sum / count;
printf("Average: %lf\n", average);
} else {
// Cannot compute the average
puts("You didn't enter any value. Cannot compute the average.\n");
}
// End function
return;
}
if ((grade < -1) || (100 < grade)) {
puts("Error, incorrect input.\n");
// Invalid input, ignore it
continue;
}
sum += grade;
count ++;
}
}
Quite a few corrections need to be made.
The while loop in the calculateAverage() function. That's an infinite loop buddy, because you are not changing the value of that coolValue variable anywhere inside, instead you make it 1 only when it exits the loops, which it never will.
So, use while(1) {...}, and inside it, check for the stopping condition, i.e, if (grade == -1) { ... } and inside it calculate and print the average and return. This will automatically break the while.
You're not checking if the input grade is actually a valid integer or not. Check the value of scanf for that, i.e, use if (scanf("%d", &grade) != 1) { ... }
The expression sum = +grade; is just another way of writing sum = 0+grade which in turn is nothing but sum = grade. Replace this with sum += grade;. This is the right way to write a shorthand for addition.
Two return statements..a very wrong idea. First of all, a function can have just one return(in an obvious way I mean, at once). Secondly, the function calculateAverage() is of return-type void. there's no way how you can return double value from it. So remove these two statements.
I have attached the code below which works. Also do go through the output which I have attached.
CODE:
#include <stdio.h>
void calculateAverage()
{
int grade, count = 0, sum = 0;
double average;
printf("\nenter the grades... enter -1 to terminate the entries\n.");
while (1) {
printf("\nEnter the grade: ");
if (scanf("%d", &grade) != 1) {
printf("\nInvalid characters entered!!!");
continue;
}
else if(((grade > 100) || (grade < -1))) {
printf("\nInvalid grade entered!!!");
continue;
}
else {
if (grade == -1) {
average = sum/count;
printf("\nAverage value of grades: %.3lf",average);
return;
}
else {
sum += grade;
count++;
}
}
}
}
int main(void)
{
calculateAverage();
return 0;
}
OUTPUT:
enter the grades... enter -1 to terminate the entries.
Enter the grade: 50
Enter the grade: 100
Enter the grade: 60
Enter the grade: -1
Average value of grades: 70.000
Perhaps it is better for the function to be of type double instead of void. Although it is not my favorite solution it is close to what you want.
#include <stdio.h>
double calculateAverage(void)
{
double average;
int sum = 0, count=0, grade;
while (1)
{
scanf("%d", &grade);
if ((grade > 100) || (grade < -1))
printf("Error, incorrect input.\n");
else if (grade != -1)
{sum = sum+ grade; count = count + 1;}
else
break;
}
if (count==0)
average=-1.0; //none valid input. Notify the main()
else
average=(double)sum/count;
return average;
}
int main(void)
{
double result;
result= calculateAverage();
if (result!=-1.0)
printf("\n average= %lf",result);
else
printf("No grades to calculate average");
getchar();
return 0;
}

How to create C program to determine lagest number by entered value?

I've created a program to determine largest number, but my lecturer says it isn't perfect, can anybody make it perfect?
#include <stdio.h>
int main () {
double a,b=0,n, i;
printf("limit of n input: ");
scanf ("%lf",&n);
for (i=1;i<=n;i++) {
scanf("%lf",&a);
if (a>b) b=a;
}
printf("%.2lf", b);
return 0;
}
If by "not perfect" she meant "doesn't properly handle negative numbers or an empty set", then you'd want to
Treat n<1 as a special case (why should 0 be the largest of an empty set?)
Read the first number outside of the loop, so you're not making as assumption as to the smallest possible number
I would do it that way, sorry for the mass of text. I think it is coming from the typical Objective-C style programming with long words:
#include <stdio.h>
int clean_stdin() {
while (getchar()!='\n');
return 1;
}
int main(int argc, char *argv[]) {
char c;
signed int count = 0; // number of numbers to scan
unsigned int fireErrorMessage = 0;
do {
if (fireErrorMessage == 1) {
printf("You entered not a positive natural number. Please enter a number >0 Examples: 1 22 4012\n"); // output for the user
}
if (fireErrorMessage == 0) {
fireErrorMessage = 1;
}
printf("How many integers do you want to insert (Inser a number >0)? ");
} while (((scanf("%d%c", &count, &c) != 2 || c != '\n') && clean_stdin()) || count < 1);
signed int indexOfNumber; // for index, declared outside because of output at the end
signed int highestNumberIndex;
double highestNumber; // saving the highest value in a helper variable
fireErrorMessage = 0;
for (indexOfNumber = 1; indexOfNumber <= count; indexOfNumber++) {
double scannedNumber;
do {
if (fireErrorMessage == 1) {
printf("You entered not a number. Please enter a number. Examples: 3.0 -1 14\n"); // output for the user
}
if (fireErrorMessage == 0) {
fireErrorMessage = 1;
}
printf("Input number %d: ", indexOfNumber); // output for the user
} while (((scanf("%lf%c", &scannedNumber, &c) != 2 || c != '\n') && clean_stdin()));
fireErrorMessage = 0;
if (indexOfNumber == 1 || scannedNumber > highestNumber) {
highestNumberIndex = indexOfNumber;
highestNumber = scannedNumber;
}
}
printf("Highest input number on index %d, the value is about %.2lf\n", highestNumberIndex, highestNumber);
return 0;
}
Output
How many integers do you want to insert (Inser a number >0)? aa5
You entered not a positive natural number. Please enter a number >0 Examples: 1 22 4012
How many integers do you want to insert (Inser a number >0)? -3
You entered not a positive natural number. Please enter a number >0 Examples: 1 22 4012
How many integers do you want to insert (Inser a number >0)? 3
Input number 1: aa
You entered not a number. Please enter a number. Examples: 3.0 -1 14
Input number 1: -50.0001
Input number 2: 51a
You entered not a number. Please enter a number. Examples: 3.0 -1 14
Input number 2: -1.00
Input number 3: -0.1
Highest input number on index 3, the value is about -0.10
This code caters for negative, not a number input for the loop index as well as negative and not a number inputs inside the loop. Thanks
#include <stdio.h>
#include <math.h>
int main () {
int n, i;
double a,b=0;
printf("limit of n input: ");
scanf ("%lf",&n);
if(n < 0){
printf("value of n cannot be negative");
return 0;
}
else if (n == 0)
return 0;
else if (isnan(n))
return 0;
else{
for (i=1;i<=n;i++)
{
scanf("%lf",&a);
if(!isnan(a) && a > 0)
{
if (a>b) b=a;
}
}
printf("%.2lf", b);
return 0;
}
}

Resources