Press q to quit outputs incorrect math - c

I am trying to use "Press 'q' to quit" functionality to exit a do...while loop for calculating the average of a series of user-defined integers. Following several examples I was able to get the exit value to work but it is being included as part of calculating the average.
Example:
quixote#willow:~$ gcc sentinel-borked.c -o sentinel-borked
sentinel-borked.c: In function 'main':
sentinel-borked.c:22:13: warning: assignment makes integer from pointer without a cast [-Wint-conversion]
sum = sum + value;
^
quixote#willow:~$ ./sentinel-borked
Enter an answer string or q to quit: 1
Enter an answer string or q to quit: 1
Enter an answer string or q to quit: q
Count is: 3
Average is: 214197589.333333
quixote#willow:~$
I know that the "q" is being treated as an integer, but I'm not sure how to re-write my code to escape it. :(
The simplest workaround that I can think of is to prompt the user for an end point (i.e. "how many integers are you averaging?") and use that, but I would really like to figure this out.
Here is the code I have so far.
#include <stdio.h>
#include <string.h>
int main ()
{
/* variable definition: */
int count, sum;
double avg;
char *value;
/* Initialize */
count = 0;
sum = 0;
avg = 0.0;
do {
// Loop through to input values
printf("\nEnter an answer string or q to quit: ");
fgets(value, 10, stdin);
if (value >= 0){
sum = sum + value;
count = count + 1;
}
else {
printf("\nValue must be positive");
}
} while (value[0] != 'q');
// Calculate avg. Need to type cast since two integers will yield an integer
printf("\nCount is: %d", count);
avg = (double) sum/count;
printf("\nAverage is: %lf\n", avg);
return 0;
}
EDIT: Replaced screenshot with plain-text inside of a code block. Original image still located at: https://i.stack.imgur.com/qza1N.png

Try this:
#include <stdio.h>
#include <string.h>
int main ()
{
/* variable definition: */
int count, sum;
double avg=0;
char value[10]="";//make value an array or allocate memory for it using malloc and also null initiate it
/* Initialize */
count = 0;
sum = 0;
avg = 0.0;
fgets(value,10,stdin);
if(value[strlen(value)-1]=='\n'){//if the user enters a string less than 10 chars a newline will also be stored inside the value array
value[strlen(value)-1]='\0';//you need to remove that \n and replace it with null
}
else{
while((getchar())!='\n');//just removing any extra chars left(when the user enters a string greater than 10 chars)
}
while(value[0]!='q'){//beware it will only check for the first char of the array to be q, anything else will still proceed the loop
sum+=strtol(value,NULL,10);//use this to convert integers inside the array to long ints(many other ways exists)
count++;
fgets(value,10,stdin);//overwrite value each time to get input
if(value[strlen(value)-1]=='\n'){
value[strlen(value)-1]='\0';
}
else{
while((getchar())!='\n');
}
}
// Calculate avg. Need to type cast since two integers will yield an integer
printf("\nCount is: %d", count);
if(count==0){
printf("\nAverage is: %lf\n", avg);
}
else{
avg = (double) sum/count;
printf("\nAverage is: %lf\n", avg);
}
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

While loop will not print the smallest number entered

I am creating a program that uses a while loop to provide multiple pieces of information from input given by the user. One of these pieces is the smallest number entered. I can't get it to print anything but 0. Any idea why?
#include <stdio.h>
#include <stdlib.h>
int main()
{
float num, sum = 0, sm, lg = 0, count = 0, avg = 0;
printf("Please enter a series of numbers (-1 to terminate): ");
scanf("%f", &num);
while(num > -1){
sum += num;
if(lg < num)
lg = num;
if(sm > num)
sm = num;
scanf("%f", &num);
count++;
avg = sum / count;
}
printf("The sum of your numbers is: %.4f\n", sum);
printf("You entered %.4f numbers\n", count);
printf("The average of the numbers you entered is: %.4f\n", avg);
printf("The smallest number you entered is: %.4f\n", sm);
printf("The Largest number you entered is: %.4f", lg);
return 0;
}
ex entry- 15
43
22.5
57.6
-1
Output-
sum:138.1000
4 numbers entered
average: 34.5250
smallest: 0.0000
Largest: 57.6000
In your code, sm has an undefined value because you aren't initializing it. You can initialize it to something like a very large number (or, even better, INFINITY) so it can be properly compared. The same goes for lg: if you want it to work for negative values too, you should initialize it with a very small value (-INFINITY). You can use INFINITY by including math.h.
the posted code does not compile!
first, because it is missing the needed #include statements for the needed header files. Specifically:
#include <stdio.h>
Then regarding this code block:
if(sm > num)
sm = num;
on the first pass through the while() loop, the variable sm is not initialized so accessing its' contents is undefined behavior.
Also, if using visual studio in debug mode, then all the stack is cleared to 0, so no other value will ever be assigned to it. This is why the algorithm always returns 0
Here's what I regard as a workable program. It uses double rather than float; if you insist, you can change the types and (input) formats to suit your desires. It has no particular limit on the number of rows it will accept. It doesn't output anything if there were no inputs. There is absolutely no need to use an array for the calculations. It uses use +∞ and -∞ to initialize the smallest (min) and largest (max) values respectively. Even if the only input is +∞ or -∞ (spelled +Inf or -Inf, or +Infinity or -Infinity, optionally without the + sign, and with upper-case, lower-case or mixed-case spelling) the correct values are produced.
#include <stdio.h>
#include <math.h>
int main(void)
{
double min = +INFINITY;
double max = -INFINITY;
double sum = 0.0;
size_t cnt = 0;
double value;
while (scanf("%lf", &value) == 1)
{
sum += value;
cnt++;
if (value > max)
max = value;
if (value < min)
min = value;
}
if (cnt > 0)
{
printf("Count = %zu\n", cnt);
printf("Sum = %g\n", sum);
printf("Min = %g\n", min);
printf("Max = %g\n", max);
printf("Average = %g\n", sum / cnt);
}
return 0;
}
Given ten random values between -1E6 and +1E6:
989375.672
-826955.668
224850.463
-401605.702
-45457.787
259618.099
821069.496
-268408.724
-512449.113
-46404.246
the program produces the output:
Count = 10
Sum = 193632
Min = -826956
Max = 989376
Average = 19363.2
I should probably put a bit more control on the output formatting, but the %g option is quite useful for numbers with wide ranges. Given the input data, using %11.3f would work well (it was used to format the output from the random number generator I used).

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!!!
}

Infinite Recursion loop C

We have been learning about recursion vs iteration in C this week and we were required to make a program that recursively determines the value of the nth term of a geometric sequence defined by the terms a, ar, ar^2, ... ar^(n-q).
For the most part, I think I have it figured out, as it seems to display the correct values per run, but it doesn't manage to break the recursion when the tested value reaches zero. Also, if possible to get a better explanation of recursion, and some examples of when recursion would be preferred over iteration as I'm still struggling with the concept.
// 2/20/2018
//Lab 6 Solution for Page 369 PE 4 B
//including libraries to be used
#include <stdio.h>
#include <math.h>
int main() {
//Function prototype
double goAnswer(int *, double, double, double, double *, int);
//Declaring variables
int nValue = 0;
double ratio = 0;
double firstTerm = 0;
double answer = 0;
double addedAnswer = 0;
int count = 1;
//Setting up to ask for each value
printf("Please enter in the value of n: ");
scanf("%d", &nValue);
printf("Please enter in the ratio you'd like to use: ");
scanf("%lf", &ratio);
printf("Please enter in the first term to use: ");
scanf("%lf", &firstTerm);
addedAnswer = goAnswer(&nValue, ratio, firstTerm, answer, &addedAnswer,
count);
//Printing out the value of the first nth terms
printf("The value of all terms added together is: %lf\n", addedAnswer);
return 0;
}
//function header
double goAnswer(int *nValue, double ratio, double firstTerm, double answer,
double *addedAnswer, int count) {
if (nValue == 0){
return 0;
}
else{ //This part calculates the answer, prints the value to the screen,
adds the answer to a running sum, decreases the nValue by one and calls the
function again with the lower nValue
answer = firstTerm * pow(ratio, count);
printf("The value of term %d is: %lf\n", count, answer);
printf("This is the nValue: %d \n", *nValue);
*addedAnswer += answer;
nValue -= 1;
return (goAnswer(nValue, ratio, firstTerm, answer, addedAnswer,
(count + 1)));
}
}

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
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.
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;
}
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
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.
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.

Resources