(Visual Studio)Calculation _using for sentence - c

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

Related

multiply numbers untill the user enters 0

I don't know why but the loop doesn't stop even when I enter 0. can someone help me with this?
int main(void)
{
float number,product = 1;
printf("Provide floats separated by a line: \n");
scanf("%f" , &number);
while(number != 0)
{
product *= number;
if(number == 0)
break;
}
printf("The product of your values is: %.2f" , product);
printf("\n");
}
You'll need to place the scanf call inside the loop to repeatedly ask the user for input. As it is you only ask once, and then loop forever on the same value.
Here we place the call in the predicate itself:
#include <stdio.h>
int main(void) {
float number = 0,
product = 1;
puts("Provide floats separated by a line:");
while (scanf("%f" , &number) == 1 && number)
product *= number;
printf("The product of your values is: %.2f\n" , product);
}
You should always check the return values of your I/O functions. scanf returns the number of conversions that took place, which here should be 1. On error, EOF, or number being 0 we do not continue the loop.

Using a for loop to add integers from an array

I'm writing a program that takes in your student number(8 digits long), prints each digit on its own new line, and then gets the sum of all the digits in the number
(E.g. Student Number - 20305324, Sum - 19)
#include <stdio.h>
#include <string.h>
int main(void) {
char student_number[8];
int i = 0;
int sum = 0;
printf("Enter your student number: ");
scanf("%s", student_number);
// ensures input is only 8 digits - WORKS
while (strlen(student_number) < 8 || strlen(student_number) > 8){
printf("Enter your student number: ");
scanf("%s", student_number);
}
// prints each digit of the student number on a new line - WORKS
while (student_number[i] != '\0'){
printf("%c\n", student_number[i]);
i++;
}
// sum all the digits in the student number and print - DOESN'T WORK
for (i=0;i<8;i++){
sum = sum + student_number[i];
printf("%d\n", sum);
}
printf("Sum of the numbers is %d", sum);
}
OUTPUT
The problem I'm encountering is when my for loop attempts to add each digit in the student number. The output I expect here is 19, but for some reason the sum evaluates to some bizarre number like 403
}
Would someone mind pointing out where exactly the fault in my for loop is or if it is elsewhere? Thanks :)
Firstly, your array char student_number[8]; cannot hold 8-character string because there are no room for terminating null character. You must allocate one more element.
Then, you should convert the characters to corresponding numbers. Character codes for digits are defined to be continuous, so this can be done by subtracting '0' from the character code.
Also you should set a limit of length of string to read via scanf() to avoid buffer overrun. One more good practice is checking the return values of scanf() to see if something is successfully read.
Fixed code:
#include <stdio.h>
#include <string.h>
int main(void) {
char student_number[10]; // *** allocate enough elements (one more than needed to catch too long input)
int i = 0;
int sum = 0;
printf("Enter your student number: ");
if(scanf("%9s", student_number) != 1){ // *** limit the length to read and check the result
fputs("read error\n", stderr);
return 1;
}
// ensures input is only 8 digits - WORKS
while (strlen(student_number) < 8 || strlen(student_number) > 8){
printf("Enter your student number: ");
if(scanf("%9s", student_number) != 1){ // *** limit the length to read and check the result
fputs("read error\n", stderr);
return 1;
}
}
// prints each digit of the student number on a new line - WORKS
while (student_number[i] != '\0'){
printf("%c\n", student_number[i]);
i++;
}
// sum all the digits in the student number and print -DOESN'T WORK
for (i=0;i<8;i++){
sum = sum + (student_number[i] - '0'); // *** convert characters to numbers before adding
printf("%d\n", sum);
}
printf("Sum of the numbers is %d", sum);
}
When you read characters as a string, the values of the char objects are codes for the characters. Your C implementation is likely using ASCII codes, in which 48 is the code for “0”, 49 is the code for “1”, 65 is the code for “A”, and so on.
To convert a code x for a digit to the value of the digit, use x - '0'.
I think that the task was to read the number not the string.
void printDigitsAndSum(unsigned number)
{
unsigned mask = 1;
unsigned sum = 0;
while(number / (mask * 10)) mask *= 10;
while(mask)
{
printf("%u\n", number / mask);
sum += number / mask;
number %= mask;
mask /= 10;
}
printf("Sum: %u\n", sum);
}
int main(void)
{
unsigned number;
if(scanf("%u", &number) == 1)
printDigitsAndSum(number);
else printf("Wrong number\n");
}
https://godbolt.org/z/1edceh

Press q to quit outputs incorrect math

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

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.

How to prevent an infinite loop with scanf failure

The Code is supposed to make change for a dollar and works fine. but the professor says that he will be enter random numbers along with letters. It works fine with numbers but when a letter is entered an infinite loop will occur any suggestions?
#include <stdio.h>
#include <stdlib.h>
#define amtPaid 1
#define SENTINAL -1
int quarters(int numChange);
int dimes(int numChange);
int nickels(int numChange);
int pennies(int numChange);
int main(void)
{
double amtDue = 0; // how much is paid
while(1){
printf("\nPlease enter the price less than 1 dollar: ");
scanf(" %lg", &amtDue);
int changeReturn = (amtPaid - amtDue) * 100 + 0.5; // convert decimal to whole number
int updated = 0; // remaining change after amt of change
int numberQuarters = quarters(changeReturn); // number of quarters needed
if(changeReturn >= 0 && changeReturn <= 100){ // if changereturn is between 0 and 100 execute code
printf("\nNice!");
printf("\nWe owe you %i cents" , changeReturn);
if(numberQuarters >= 0){ // get and print number of quarters
printf("\nQuarters: %i", numberQuarters);
updated = changeReturn % 25;
}
if(dimes(updated) >= 0){ // get and print number of dimes
printf("\nDimes: %i", dimes(updated));
updated = updated % 10;
}
if(nickels(updated)>= 0){ // get and print number of nickels
printf("\nNickels: %i", nickels(updated));
updated = updated % 5;
}
if(pennies(updated) >= 0){ // get and print number pennies
printf("\nPennies: %i", pennies(updated));
}
}
else if(amtDue == SENTINAL){
break;
}
else {
printf("That does not make sense to me. please type a valid number");
}
printf("\n %g", amtDue);
}
return 0;
}
int quarters(int numChange){
int numQuarters = 0;
numQuarters = numChange / 25;
return numQuarters;
}
int dimes(int numChange){
int numDimes = 0;
numDimes = numChange / 10;
return numDimes;
}
int nickels(numChange){
int numNickels = 0;
numNickels = numChange / 5;
return numNickels;
}
int pennies(numChange){
return numChange;
}
In case an inappropriate value is supplied other than the expected value of the format specifier with scanf(), the scanf() will fail and the inappropriate value will remain in the input buffer, providing the feed to next scanf(), only to cause successive failures. In that case, you need to clean up the input buffer before going for next input. You can use something like
check the return value of scanf()
In case of failure, use while( getchar() != '\n' ); to clean the input buffer.
That said, int nickels(numChange) is now invalid in c (C99 onwards). You have to make it as int explicitly.
Instead of using scanf(" %lg", &amtDue);, get the user input as a string, so you can do proper checking.
char input[500];
fgets(input, 500, stdin);
// do some input checking
double val = atof(input);
// do calculations on the number
To check, there's all kinds of functions to help you in ctype.h, one that you might find interesting is isalpha.
Manual References:
fgets
atof converts string to double
atoi converts string to integer
isalpha

Resources