I am trying to design a program that calculates the average of any desired number of floats, until EOF. The program should also check if the input was correct and return "Wrong Input" when e.g. entering a string. The code I wrote works, but it gives wrong ouputs for the average. Can anyone tell me why?
#include <stdio.h>
int main(void) {
int times = 0;
float sum = 0;
float scan;
float avrg;
int scanvalue = 1;
while (scanvalue == 1) {
scanvalue = scanf("%f", &scan);
sum = sum + scan;
times++;
}
if (scanvalue == EOF) {
avrg = sum / times;
printf("The average is %f\n", avrg);
} else {
printf("Wrong input");
}
return 0;
}
Best regards.
You don't check scanvalue after scanf() and still use the value at scan which is messing up the average. Note that when scanf() returns EOF it will not modify scan, and thus it will still have its last value so you are adding the last value twice.
But if you enter invalid input at the beginning then the behavior is undefined, change it to
while ((result = scanf("%f", &value)) == 1) {
}
Also, I deliberately changed the names of your variables to illustrate a better way of naming them.
You need to check scanvalue after the scanf, otherwise times will be incremented even if you enter EOF and sum will get a wrong input, thus resulting the average being wrong/messed.
So you should change
while (scanvalue == 1) {
scanvalue = scanf("%f", &scan);
sum = sum + scan;
times++;
}
To
while (scanvalue == 1) {
scanvalue = scanf("%f", &scan);
if (scanvalue != 1)
break;
sum = sum + scan;
times++;
}
Related
So I wrote a simple program that converts a decimal to binary, that only accepts positive whole numbers. So numbers like -2 and 1.1 would output "Sorry, that's not a positive whole number." It infinitely asks the user to input a number until the user presses ctrl + D. However when I tested it it prints out the "Sorry..." statement before it ends the program.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void DecToBin(int userInput){
int binary[32];
int i = 0;
while (userInput > 0) {
binary[i] = userInput % 2;
userInput /= 2;
i++;
}
for (int j = i - 1; j >= 0; --j) {
printf("%d", binary[j]);
}
}
int main(void) {
double userDec;
int temp;
printf("Starting the Decimal to Binary Converter!\n\n");
while(!feof(stdin)) {
printf("Please enter a positive whole number (or EOF to quit): ");
scanf("%lf", &userDec);
temp = (int)(userDec);
if ((userDec > 0) && (temp / userDec == 1)) {
printf("\n\t%.0lf (base-10) is equivalent to ", userDec);
DecToBin(userDec);
printf(" (base-2)!\n\n");
}
else {
printf("\tSorry, that was not a positive whole number.\n");
}
}
printf("\n\tThank you for using the Decimal to Binary Generator.\n");
printf("Goodbye!\n\n");
return 0;
}
(All the tab and newlines are just how it's supposed to be formatted so don't pay attention to that)
So from what I'm understanding, my program reads ctrl + D as the else in my while loops. So, any idea why that is?
It seems like you think C-d would trigger some kind of break in the code. Like the keyword break. This is not true.
Read this post to see what's happening when you press C-d: https://stackoverflow.com/a/21365313/6699433
That does not cause anything special to happen in the C code. scanf will simply not read anything. After the scanf statement, the code will continue as usual, so the code WILL unconditionally enter the if statement.
This is also a pretty severe thing, because you'll be using userDec uninitialized. scanf returns the number of successful assignments, and you should always check the return value. So in your case you want this:
if(scanf("%lf", &userDec) != 1) { /* Handle error */ }
Because if scanf does not return 1, userDec is unassigned.
To achieve what you want, simply do this:
if(scanf("%lf", &userDec) != 1)
break;
I want to strictly limit a user's input on an integer in this program to 2-12 only. How do I do that?
#include <stdio.h>
int main(){
int i;
scanf("%d", &i);
int diceThrown, diceResult;
int sum = 0;
for(diceThrown = 1; diceThrown <= i; diceThrown++){
scanf("%d", &diceResult); //limit this input to 2-12 only, how?
sum += diceResult;
}
if(sum >= 40){
sum = sum % 40;
if(sum == 12){
printf ("28\n");
} else if(sum == 35){
printf ("7\n");
} else{
printf ("%d\n", sum);
}
} else if(sum < 40){
if(sum == 12){
printf ("28\n");
} else if(sum == 35){
printf ("7\n");
} else{
printf ("%d\n", sum);
}
}
return 0;
}
Also just to clarify, that I'm still a beginner in programming (like only 2 months into C.SCi course), so if you could explain it to me like I'm not a expert that would be great.
scanf has no functionality to do what you want. You can just use an if to validate input.
if(scanf("%d", &diceResult) != 1 || diceResult < 2 || diceResult > 12) {
//handle invalid input here
}
If the input is invalid it is up to you what you want to do. You could ignore the input and ask the user to enter a valid number, you can quit the whole program or just ignore the error, or something else entirely.
You can also check the input repeatedly with an while:
while(scanf("%d", &diceResult) != 1 || diceResult < 2 || diceResult > 12) {
//prompt user to enter valid input here
}
As mentioned by chux, part of handling invalid input would be to cosume the invalid input and check for EOF.
The scanf("%d", &diceResult) != 1 will assure, that scanf actually read exactly one number and no parsing errors occurred.
Consider this:
#include <stdio.h>
int main(){
int x;
do
{
printf("give a number between [2-12]\n");
scanf ("%d",&x);
}
while(x<2 || x>12);
return 0;
}
You can use a do-while loop so that you only take the values that are between the 2-12 range. That way you can force the user to give an integer as an input that is in the range that you ask for, in that case from [2,12]. Otherwise the program will turn back and request a valid input again.
So, I have a Program which checks if a Triangle is valid, here is the code.
#include <stdio.h>
int main()
{
int side1, side2, side3;
/* Initially assume that the triangle is not valid */
int valid = 0;
/* Input all three sides of a triangle */
printf("Enter three sides of triangle: \n");
scanf("%d%d%d", &side1, &side2, &side3);
if((side1 + side2) > side3)
{
if((side2 + side3) > side1)
{
if((side1 + side3) > side2)
{
/*
* If side1 + side2 > side3 and
* side2 + side3 > side1 and
* side1 + side3 > side2 then
* the triangle is valid. Hence set
* valid variable to 1.
*/
valid = 1;
}
}
}
/* Check valid flag variable */
if(valid == 1)
{
printf("Triangle is valid.");
}
else
{
printf("Triangle is not valid.");
}
return 0;
}
But what I want to do is add a Prompt to ask how many triangles to check, so I would add something like this
#include <stdio.h>
int main()
{
int repeats;
/* Input the amount of repeats */
printf(" the amount of repeats: \n");
scanf("%", &repeats);
...
The amount of entered should be the amount of triangles the user wants to check.
Bonus Question: How to check that the user entered only a number and no letter.
Thanks in advance.
The
scanf("%", &repeats);
must've been
scanf("%d", &repeats);
as repeats is an int.
You could just place the block of code that you want to execute repeatedly in a loop like
for(i=0; i<repeats; ++i)
{
//your code
}
To check whether the user entered a number and not a character check the return value of scanf(). It returns the number of successful assignments it did.
Since the format specifier is %d in
scanf("%d", &repeats);
scanf() expects an integer. But if a character was given out instead, it won't assign (and would return 0 in this case) and the input (which is not a number) will remain unconsumed in the input buffer.
if( scanf("%d", &repeats)!=1 )
{
//value was not read into 'repeats'
}
This might be of interest to you.
Now if the invalid input remains in the input buffer, it can cause problems with the next scanf(). So it must somehow be consumed.
You could do something like
int ch;
while( (ch=getchar())!='\n' && ch!=EOF );
This would consume from the input buffer till the next new line (\n).
Have a look here.
And your
if((side1 + side2) > side3)
{
if((side2 + side3) > side1)
{
if((side1 + side3) > side2)
{
valid = 1;
}
}
}
could be made
if( (side1 + side2)>side3 && (side2 + side3)>side1 && (side1+side3)>side2 )
{
valid = 1;
}
and you don't really need the extra parenthesis because arithmetic operators have greater precedence than relational operators which in turn have greater precedence than logical operators.
Look here.
you could achieve that simply by wrapping a do while around your code so that it looks something like that
#include <stdio.h>
int main()
{
int repeats = 0, counter = 0;
/* Input the amount of repeats */
printf(" the amount of repeats: \n");
scanf("%d", &repeats);
do {
...
check here if its a triangle
...
counter++;
} while(counter < repeats);
i need help with short Code in C. I must read floats on input line seperated with space and input is ended with float 0 or EOF.
How to do this if i dont know how many numbers or in input, or how it works and ask to EOF if i am reading just numbers and not chars?
Thanks for any response.
example of input in one line:
12 11 10 45 50 12 EOF
12 10 11 45 0
int main(void)
{
float num;
float sum = 0;
do{
scanf("%f", num);
sum += num;
} while(EOF || num == 0);
return 0;
}
From the man page of scanf -
scanf returns the number of items successfully matched and assigned
which can be fewer than provided for, or even zero in the event of an
early matching failure. The value EOF is returned if the end of input
is reached before either the first successful conversion or a matching
failure occurs.
This means that scanf will return EOF only when it encounters EOF as the first input when it is called because EOF must be preceded with a newline '\n' else it won't work (depending on the OS). You must also account for the matching failure scanf may encounter.
#include <stdio.h>
int main(void) {
float num;
float sum = 0;
int val;
while((val = scanf("%f", &num)) != EOF && val == 1) {
sum += num;
}
if(val == 0) {
printf("matching failure. input is not a float.\n");
}
else {
printf("end of input.\n");
}
return 0;
}
From scanf reference:
On success, the function returns the number of items of the argument
list successfully filled. This count can match the expected number of
items or be less (even zero) due to a matching failure, a reading
error, or the reach of the end-of-file.
If a reading error happens or the end-of-file is reached while
reading, the proper indicator is set (feof or ferror). And, if either
happens before any data could be successfully read, EOF is returned.
If an encoding error happens interpreting wide characters, the
function sets errno to EILSEQ.
So, you may rewrite your do-while loop to something like
int retval;
while((retval = scanf("%f", &num)) != EOF && retval > 0 && num != 0) {
sum += num;
}
if(retval == 0) {
printf("input read error.\n");
}
to match your constraints.
Also note you need to prefix your variable with & when passing it to scanf(), since the function expects a pointer to deal with (you need to pass variable address).
EDIT:
see this topic concerning EOF problems in Windows
You can re write your code like this
int main(void)
{
float num;
float sum = 0;
do
{
scanf("%f", &num);
sum += num;
} while((!feof(stdin)) && (num != 0));
printf("%f", sum);
return 0;
}
Here feof indicates end of input stream.
The following may be a slightly more robust way to do this:
#include <stdio.h>
#include <string.h>
int main(void) {
int sum=0;
int num;
char *p;
char buf[1000];
fgets(buf, 1000, stdin);
p = strtok(buf," ");
while(p!=NULL) {
if(sscanf(p, "%d", &num) == 1) sum+=num;
p = strtok(NULL, " ");
}
printf("the sum is %d\n", sum);
}
Test:
> testme
1 2 3 4 0
the sum is 10
> testme
1 2 3 4 ^D
the sum is 10
Note - you have to enter ctrl-D twice to get the desired effect when you are at the end of a line.
you can get your doubt clear by reading "C programming a modern approach by K N King"
This book provides proper clarification on this topic
Test the result of scanf() for 0, 1 or EOF.
Test the value scanned for 0.0.
int main(void) {
float num;
float sum = 0;
int cnt;
while ((cnt = scanf("%f", &num)) == 1) {
if (num == 0.0) break;
sum += num;
}
// cnt should be EOF, 0 or 1
if (cnt == 0) {
printf("Input is not a number\n");
}
else {
printf("Sum %f\n", sum);
}
return 0;
}
Although, in general, scanf() returns values EOF, 0, 1, ... "number of format specifiers", a value of 0 occurs rarely. Example input is "+".
I am doing a lab for an intro programming class
I have to make sure that an integer is entered. I thought this would do it but when I put in a letter it repeats in an endless loop.
I found this solution in another post
int num;
char term;
if (scanf("%d%c", &num, &term) != 2 || term != '\n')
printf("failure\n");
else
printf("valid integer followed by enter key\n");
But im not sure what I did wrong. Why is it not working in my code?
#include <stdio.h>
int main(void)
{
int oneVar;
char term;
double numOne;
double numTwo;
double sum;
double dif;
double quo;
double mult;
int checker = 1;
do
{
printf("Please choose one of the following:\n""1) Add\n""2) Subtract\n""3) Divide\n""4) Multiply\n""5) Quit\n");
if (scanf("%d%c" , &oneVar ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
else if (oneVar == 5)
{
printf("Thank you. Goodbye.\n");
checker = 0;
}
else if (oneVar != 1 && oneVar !=2 && oneVar != 3 && oneVar != 4)
{
printf("This is not a valid input\n\n");
checker = 1;
}
else
{
printf("Please enter the first number:\n");
if (scanf("%lf%c" , &numOne ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
printf("Please enter the second number:\n");
if (scanf("%lf%c" , &numTwo ,&term) != 2 || term != '\n')
{
printf ("This is not valid input\n\n");
checker = 1;
}
else if (oneVar == 1)
{
sum = numOne + numTwo;
printf("The sum is: %.2lf\n" ,sum);
checker = 0;
}
else if (oneVar == 2)
{
dif = numOne - numTwo;
printf("The difference is: %.2lf\n" ,dif);
checker = 0;
}
else if (oneVar == 3)
{
quo = numOne / numTwo;
printf("The quotient is: %.2lf\n" ,quo);
checker = 0;
}
else if (oneVar == 4)
{
mult = numOne * numTwo;
printf("The product is: %.2lf\n" ,mult);
checker = 0;
}
else if (oneVar == 5)
{
printf("Thank you. Goodbye.\n");
checker = 0;
}
}
} while (checker == 1);
return(0);
}
My prof posted this Im not sure how it helps but I thought it might help someone
To make sure that a user-input number is an integer you can use the notion of casting. Casting is a way to tell C to treat a variable as if it were a variable of a different type.
so, if I have something like this:
double myDouble;
myDouble = 5.43;
printf ("%d", (int) myDouble);
It will tell C to print myDouble, but to treat it like an integer. Only the 5 will be printed and you won't get any type mismatch errors. You can use casting to check to see if an input number is an integer by comparing the input to the (int) cast of the number. Something like this should work:
if(inputNum == (int) inputNum)
You'll still get 1.0 and 2.0 passing as valid numbers, but that is ok for now.
Why complicate things?
char x = 0;
scanf("%c", &x);
if (x >= 0x41 && x <= 0x7A)
printf("you entered a letter");
In ASCII table, letters have values between 0x41 ("A") and 0x7A ("z").
So, you just need to check the ASCII value of the input. :)
Using the %c to "consume" the end of line is not a good solution. If the user enters say:
123 abc<newline>
num will be 123, but term will be the space character. If you enter a letter rather than a number, the scan will stop without consuming any of the characters, the next input call will return due to the already buffered line, and may still consume nothing. Your program loops continuously because every input statement is failing to consume the newline and returns immediately. The standard input functions wait for a complete line before returning, if the line is not read completely, input functions do not need to wait.
There are a number of solutions, many of which such as the one you used are flawed, the method below, forces the input buffer to be flushed up to and including the newline.
int check = scanf( "%d", &num ) ;
while( getchar() != '\n' )
{
// do nothing
}
if( check != 2 )
printf("failure\n");
else
printf("valid integer followed by enter key\n");
If you use the %c format specifier at the end of the input, then a slightly different flush is necessary since the character input may be a newline:
int check = scanf( "%c", &ch ) ;
while( ch != '\n' && getchar() != '\n' )
{
// do nothing
}