Check user input in C with scanf() - c

Purpose:
If user input b is a float number prints floor(b), round(b), ceil(b).
Else prints scanf error: (%d)\n.
The instruction (provided by our teacher) has a code like this, which I don't understand.
Here's my code:
`
#include <stdio.h>
#include <math.h>
int main(void) {
float b;
printf("Eneter a float number");
int a=0;
a=5;
a=scanf("%d", &b);
if (a=0)
{
printf("scanf error: (%d)\n",a);
}
else
{
printf("%g %g %g",floor(b), round(b), ceil(b));
}
return 0
}

Mistake # 1
if (a=0) // condition will be always FALSE
must be
if (a==0)
or better
if (0 == a)
Mistake # 2
scanf("%d", &b); // when b is float
instead of
scanf("%f", &b);
UPDATE:
Actually, for case of checking results of scanf I personally prefer to use != with number of values entered with the last scanf. E.g. if two comma separated integers required to continue calculation snippet can be:
int x, y;
int check;
do{
printf("Enter x,y:");
check = scanf("%d,%d", &x, &y); // enter format is x,y
while(getchar()!='\n'); // clean the input buffer
}while(check != 2);
that loop will re-ask for input if check is not 2, i.e. if it is 0 (when even the first value is incorrect, e.g. abc,12) or if it is 1 (when user forgot comma or enter not a number after comma, e.g. 12,y

Code with corrections and comments - also available here - http://ideone.com/eqzRQe
#include <stdio.h>
#include <math.h>
int main(void) {
float b;
// printf("Eneter a float number");
printf("Enter a float number"); // Corrected typo
fflush(stdout); // Send the buffer to the console so the user can see it
int a=0;
// a=5; -- Not required
a=scanf("%f", &b); // See the manual page for reading floats
if (a==0) // Need comparison operator not assignemnt
{
printf("scanf error: (%d)\n",a); // A better error message could be placed here
}
else
{
printf("%g\n", b); // Just to check the input with ideone - debugging
printf("%g %g %g",floor(b), round(b), ceil(b));
}
return 0; // You need the semi-colon here
}
For VenuKant Sahu benefit
Return Value
These functions return the number of input 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. EOF is
also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set
indicate the error.

Related

Using printf() to output the correct number of decimal places?

When I enter 2, I wish to get this output:
value: 2.4
But when I do the multiplication, I am getting this:
value: 2.400000
This is my code:
#include <stdio.h>
int main()
{
float num;
float result;
printf("Number: ");
scanf("%f", &num);
result = num * 1.2;
printf("Result: %f", result);
}
What can I do?
You can specify how many digits you want to print after the decimal point by using %.Nf where N is the number of digits after the decimal point. In your use case, %.1f: printf("Result: %.1f", result).
There are some other issues in your code. You are making use of scanf(), but you are not checking its return value. This may cause your code to break.
scanf() returns the number of arguments it successfully parsed. If, for any reason, it fails, it doesn't alter the arguments you gave it, and it leaves the input buffer intact. This means whenever you try again and read from the input buffer, it will automatically fail since
it previously failed to parse it, and
it didn't clear it, so it's always there.
This will result in an infinite loop.
To solve the issue, you need to clear the input buffer in case scanf() fails. By clearing the buffer, I mean read and discard everything up until a newline (when you previously pressed Enter) is encountered.
void getfloat(const char *message, float *f)
{
while (true) {
printf("%s: ", message);
int rc = scanf("%f", f);
if (rc == 1 || rc == EOF) break; // Break if the user entered a "valid" float number, or EOF is encountered.
scanf("%*[^\n]"); // Read an discard everything up until a newline is found.
}
}
You can use it in your main like that:
int main(void) // Note the void here when a function doesn't take any arguments
{
float num;
float result;
getfloat("Number", &num);
result = num * 1.2;
printf("Result: %.1f", result); // Print only one digit after the decimal point.
}
Sample output:
Number: x
Number: x12.45
Number: 12.75
Result: 15.3

program to detect whether only integer has been given or not goes into infinite loop

// program to detect whether only integer has been given or not
int main() {
int a, b, s;
printf("Enter two proper number\n");
BEGIN:
s = scanf("%d %d", &a, &b); //storing the scanf return value in s
if (s != 2) {
printf("enter proper value\n");
goto BEGIN;
}
printf("The values are %d and %d ", a, b);
}
This program to detect whether only integer has been given or not goes into infinite loop when invalid data is entered instead of asking for new values
why doesn't the goto work here?
Note that when scanf gets bad input (for example you enter cat dog) that input remains in the input buffer until you take steps to clear it out. So the loop keeps repeating and rejecting the same input which is still there.
It is simpler to use fgets and sscanf and if the scan fails, you just forget the input string and get another.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int a, b;
char str[42];
do {
printf("Enter 2 numeric values\n");
if(fgets(str, sizeof str, stdin) == NULL) {
exit(1);
}
} while(sscanf(str, "%d%d", &a, &b) != 2);
printf("Numbers are %d and %d\n", a, b);
}
Program session:
Enter 2 numeric values
cat dog
Enter 2 numeric values
cat 43
Enter 2 numeric values
42 dog
Enter 2 numeric values
42 43
Numbers are 42 and 43
Note that goto is poor practice in C and should be used only where there is no other way of constructing the code — which there usually is.
There are multiple reasons scanf() can return a value different from 2:
there is pending input that cannot be converted according to the conversion specification. For example if there is an A pending in the input stream, the %d conversion fails and the A stays in the input stream. Your code just keeps trying this conversion and will never stop. You should read and discard the offending input before re-trying.
the input stream has had a read error or hit the end of file. If at least one conversion succeeded, the number of successful conversions is returned, otherwise EOF is returned. If EOF is returned, there is no point trying again since no more input will be available.
Note also that it is considered bad style to use goto for constructions that are better expressed with flow control statements such as while and for.
Here is a corrected version:
#include <stdio.h>
// program to detect whether only integer has been given or not
int main() {
int a, b, s, c;
printf("Enter two proper numbers: ");
for (;;) {
s = scanf("%d%d", &a, &b); //storing the scanf return value in s
if (s == 2) // conversions successful
break;
if (s == EOF) {
printf("unexpected end of file\n");
return 1;
}
/* discard the rest of the input line */
while ((c = getchar()) != EOF && c != '\n')
continue;
printf("Invalid input. Try again: ");
}
printf("The values are %d and %d\n", a, b);
return 0;
}
scanf returns the number of characters. As a result, s will be equal to the number of characters you have written is 2, then your loop will stop. The reason this runs infinitely many times is that the number of characters you have entered differed from 2. Print s to see what value it holds and you will get more information.

Scanf double in C not giving the right value

I would like to know where is my mistake.
When scanning the parameters as doubles , and immediately printing them (for checking), the print is not giving me the values that I entered.
I tried to define them as integers and it worked, but for doubles its just giving me this: a=0.00000, b=-0.00000
take a look:
#include <stdio.h>
#include <stdbool.h>
int main()
{
double a=0,b=0,c=0;
scanf("%lf",&a);
scanf("%lf",&b);
scanf("%lf",&c);
printf("%lf %lf\n",a,b);
return 0;
}
EDIT: sorry i didnt include my whole code , this is the whole code, but it still gives me the same thing.
Written as it is, your program will accept correctly formatted input for 3 floating point values and will print the first two.
What values do you enter?
What is the precise input you type into your program?
I suspect you type extra characters: scanf stops scanning on invalid input.
You should test the return value from the scanf function calls and verify that values were actually parsed.
Incidentally, the printf format for double arguments is %f, not %lf, but this should not pose a problem as the extra l is most likely ignored.
Here is a corrected version you should try to find out where the problem lies:
#include <stdio.h>
int main(void) {
double a = 0, b = 0, c = 0;
if (scanf("%lf", &a) != 1) {
printf("invalid input for a\n");
}
if (scanf("%lf", &b) != 1) {
printf("invalid input for b\n");
}
if (scanf("%lf", &c) != 1) {
printf("invalid input for c\n");
}
printf("a=%f b=%f\n", a, b);
return 0;
}

While loop for only accepting integer value and exiting on any other input

I'm running this program in C to convert Fahrenheit to Celsius and need to accept only integer value from the user.
Please tell me how I can modify this?
int main() {
int x;
double y;
while(x>0) {
printf("Enter the temperature in Fahrenheit:");
scanf("%d", &x);
y=((x-32)/1.8)
printf("%f\n",y);
}
}
The reason your code does not work is that sometimes scanf does not read anything, so it does not modify x.
You know that scanf read something by checking its return value. It returns the number of "scanned" items. In this case, the number must be 1.
When scanf returns 0 instead, you should read and discard the data in the buffer. You do it by supplying %*[^\n] format specifier, which means "read and discard input up to '\n' character. The complete snippet that reads an int until success looks like this:
while (scanf("%d", &x) != 1) {
printf("Please enter a valid number:");
scanf("%*[^\n]");
}
Note: It goes without saying that you should fix your syntax error with the missing semicolon ; on the line that computes y.
You can use below code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int x;
double y;
char str1[5];
int num1,i;
bool yes = true;
while(x>0)
{
printf("Enter the temperature in Fahrenheit:");
scanf("%s",str1);
for(i=0;str1[i]!='\0';i++)
if(!(str1[i]>=48&&str1[i]<=56))
{
printf("The value is invalid \n");
yes = false;
}
num1 = atoi(str1);
if(yes == true)
{
printf("This Number is %d\n",num1);
y=((num1-32)/1.8);
printf("%f\n",y);
}
}
}

Finding if a Number if Prime or not In C

I was writing a C Program to find if a number is prime or not. Everytime I run it and enter a number, the value of the input changes. PLease point out the loopholes.
#include<stdio.h>
#include<conio.h>
int main()
{
int x;
int y;
y=getchar();
for(x=2;x<y;++x){
if(y%x != 0 && y!=x)
printf(" THE NUMBER %d is A PRIME \n", y);
else
printf(" \r THE NUMBER %d IS NOT A PRIME", y);
break;
}
}
I use the Code::Blocks IDE with GCC Compiler
As the name implies, getchar() gets a single character from standard input. For example, if you enter 3, the y gets the ASCII code of the character '3', which is obviously not what you want.
Try scanf:
scanf("%d", &y);
getchar returns the ASCII code of a single character. Consequently, your program picks up the ASCII code of the first character of the number you input and checks if it is prime.
Instead, you need to read an integer:
scanf("%d", &y);
The complete program:
#include<stdio.h>
#include<conio.h>
int main()
{
int x;
int y;
scanf("%d", &y);
for(x=2;x<y;++x){
if(y%x != 0 && y!=x)
printf(" THE NUMBER %d is A PRIME \n", y);
else {
printf(" \r THE NUMBER %d IS NOT A PRIME", y);
break;
}
}
}
Note: You can stop when x >= sqrt(y)
Well, you are calling getchar() which is used to input a single character and this is what happens in your case:
getchar() returns a character.
Character is then converted into integer when you store it in variable of type int.
Hence that integer contains the ASCII of input character i.e. 3 will be stored as 51 that is the reason input changes.
What you need to do is to input an integer instead of character. Try this:
scanf("%d", &y);
Hope this helps.
First answers are correct about input for y:
scanf("%d", &y);
Also, please note that you should loop until square root of x, and not more if your want to optimize your algorithm (I won't demonstrate here why, it's a mathematical property).
#include <stdio.h>
#include <math.h>
// ...
int x;
int x_max;
int y;
scanf("%d", &y);
x_max = (int)floor(sqrt(y));
for(x=2;x<=x_max;++x){
// ...

Resources