Why does scanf not terminate when I expect it to - c

If I write a C program then it will not automatically get out of if else like ....
#include<stdio.h>
int main ()
{
int a, b, c, d;
printf ("enter the value ");
scanf("%d %d %d ",&a,&b,&c);
d=a+b+c;
if(d==180)
printf("triangle is valid ");
else
printf("triangle is invalid ");
return 0;
}
then it will not terminate itself.....
Can anyone help to figure out what the problem in this .....

It's the space at the end of the scanf format string. Remove that space and your program will terminate.

I guess there is inconsistency between the scanf() format string and the format you enter your data in. But seriously, you should accept some old answers before asking new questions.

Omit the spaces in the scanf string
scanf("%d%d%d",&a,&b,&c);

scanf function normally skip the space between the inputs.
In your code you ask the input in the following format
scanf("%d %d %d ",&a,&b,&c);
It is represent the 1input as 1 space,1input and 1 space, 1input and 1 space.
So if you give the three input after the enter, it will skip the new line also.
Because scanf function will take the input as non white space character.
To avoid this you need to give the 4 input. So that time, the first three inputs are stored in the variable a b c, Then next space and values are stored in the buffer.
After run the program you need to give the input like the folllowing
12 12 12 12
Here the first three inputs are stored in the a b c variables.
Otherwise your scanf format should be the following format
scanf("%d%d%d",&a,&b,&c);

Related

How to prompt the user to enter an integer and a character from the keyboard in C [duplicate]

This question already has an answer here:
How to read / parse input in C? The FAQ
(1 answer)
Closed 4 years ago.
I am trying to figure out the best way to get an integer and a character from a user
Here is what I have so far:
#include <stdio.h>
int main()
{
int a;
char b;
printf("enter the first number: \n");
scanf("%d", &a);
printf("enter the second char: \n");
scanf("%c", &b);
printf("Number %d",a);
printf("Char %c",b);
return 0;
}
The output is not shown correctly. Is there any problem with this?
Your input and output statements are fine. Just replace printf("Number %d",a); with printf("Number %d\n",a); to better format the output. Also you should change your second scanf statement to scanf(" %c", &b);. This will deal with the newline character entered after the number is inputted.
After you enter the number, you pressed the Enter key. Since the scanf function works on the input stream, when you try to process the next char after reading the number, you are not reading the character you typed, but the '\n' character preceding that. (i.e. because the Enter key you pressed added a '\n' character to your input stream, before you typed your char)
You should change your second call to scanf with the following.
scanf(" %c", &b);
Notice the added space character in the formatting string. That initial space in the formatting string helps skip any whitespace in between.
Additionally, you may want to add \n at the end of the formatting strings of both printf calls you make, to have a better output formatting.
Here you need to take care of hidden character '\n' , by providing the space before the %c in scanf() function , so the "STDIN" buffer will get cleared and scanf will wait for new character in "STDIN" buffer .
modify this statement in your program : scanf("%c",&b); to scanf(" %c",&b);

How to explain my code with scanf()?

I'm a newbie in C programming and I'm learning the scanf now.
I wrote some code and I'm trying to understand it.
Here is the code:
#include <studio.h>
int main(){
int a=1, b=2, c=3;
scanf ("%d%d", &a,&b);
scanf ("%d", &c);
scanf ("%d", &c);
printf ("a=%d\nb=%d\nc=%d\n", a, b, c);
return 0;
}
When I input
11 22 33 44
The output is
a=11
b=22
c=44
This is normal. However, when I input:
11, 22, 33, 44
Output
a=11
b=2
c=3
It looks like the commas stops the input process.
Who can explain to me why is this happening?
Actually, when putting the commas between %d%d (it is like "%d, %d"), and providing input data, the input have to be separated with commas.
Who can give me some suggestions for commas in scanf parameters?
scanf stop reading when find a character in stdin that doesn't matches the format string.
In your example, your scanf expect only character that forms an integer value. Infact, the first scanf stops when it reaches the first comma. When the other scanfs try to read in the stdin, the first character they will find will be the last character the previuos scanf read but didn't use, the comma. This is the reason why they will end soon without read anything.
If you want to use commas or other character in your input over the values you want to memorize, you have to insert them explicity in the format string.
For example with this statment:
scanf("%d, %d", &a, &b);
You are instructing the scanf to read an integer and save it in the variable a, read a comma and forget it, then read another integer and save it in the variable b. If during the parsing the scanf will find something that it is not an integer or a comma they will stop immediately without reads other values(this is the reason why b and c have the earlier value in your program).
you can use commas in scanf like this :
scanf ("%d,%d,%d", &a,&b,&c);
then you input numbers in single line seperated with commas.
11,12,13.
Note that in this scenario scanf expects single line input of numbers seperated with commas. If your input in this case will be 11 12 13 then You will now get the desired output.
Thanks for your guys reply. I tried another code:
#include <stdio.h>
int main(){
int a=1, b=2, c=3;
scanf ("%d, %d", &a,&b);
scanf ("%d", &c);
scanf ("%d", &c);
printf ("a=%d\nb=%d\nc=%d\n", a, b, c);
return 0;
}
When i input
11 22 33 44
output:
a=11
b=2
c=33
how to explain?
To second question ( do not know how to quote here :( )
First scanf expects integers seperated with commas. As you did not enter your inputs like that that scanf took first number 11 and assigned it to a (b is ignored). Second scanf took number 22 and third scanf number 33. Number 44 in the input is redundant. Thats why your output looks like that.
Note that b=2 is from previous part of code int b=2

How does scanf work in this simple program?

I have some trouble working with scanf in a while loop.
I wanted to make a program that would ask the user to write three integers and save them in an array of three positions. If the user writes something which is not an integer, the program should continue asking for an integer until (s)he enters it. But it didn't work properly.
So I tried to simplify the problem with this code:
#include <stdio.h>
int main()
{
int num1=1;
int num2=2;
int num3=3;
printf ("write a number\n");
scanf("%i", &(num1));
printf("%i\n",num1);
printf ("write a number2\n");
scanf("%i", &(num2));
printf("%i\n",num2);
printf ("write a number3\n");
scanf("%i", &(num3));
printf("%i\n",num3);
}
If the inputs are 3 integers, there's no problem. But if you write a character, for example a, for the first integer, the other 2 values are not scanned and it simply writes:
a
2
3
The last two values are the initialization values.
Can anyone tell me what I have to do?
The scanf function does not have to read after it encounters the first invalid character in the input.
The %i specifier allows a as a hexadecimal, but it MUST be preceded by 0x.
If a was the first character in the input, and it was supposed to match to %i, then scanf wouldn't have to read anything afterwards - it can stop at the first invalid character..
References:
http://www.gidnetwork.com/b-64.html
For each conversion specifier scanf tries to locate the appropriate data item. scanf reads the item, stopping when it encounters a character that can't possibly belongs to the item. If any item is not read successfully then scanf returns immediately without looking at the rest of the format string.
When you enter a 5 10, scanf finds a for the specifier %i. It immediately returns and stops reading other inputs 5 and 10.

Spaces in scanf leading to abnormal results

Through my search for a solution I found this question.
Which made me think and make some experiments:
Case 1
#include<stdio.h>
main()
{ char a;
//some code
scanf("%c",&a);
/*This code might not be evaluated(missed)
sometimes*/
//This is how it is solved
scanf(" %c",&a);
//the rest of code
}
case 2
#include<stdio.h>
main()
{ int a;
//some code
scanf(" %d ",&a);
//this one will take 2 numbers instead of one
//the rest of code
}
I don't know much about c language so it would be appreciated if someone explains these results to me.(I'm using turbo c++ if it matters.)
A couple of general notes:
If you want to ask questions about C it would be beneficial for you to read about how the functions work. There is a lot of documentation available online for scanf() for example.
It's always better when you can give full compile-able examples rather than //some code
So in your first case the example would be:
char a, b;
scanf("%c", &a);
scanf("%c", &b); // this one will be "missed"
The reason is that when you enter a character in to stdin you're getting two characters really, what was typed plus an invisible newline character ('\n'). So really the second scanf isn't "missed" it's just picking up a character that doesn't have an ASCII representation.
If you printed these with:
printf("%c %d\n%c%d\n", a, a, b, b);
you would see:
>> ./my_prog
>> a
>> a 97
10
Because you entered "a\n" and the two scanf's read first the "a" then the "\n" respectively.
Using a scanf with a space before it:
scanf(" %c", &b); // this one will work instead
Will tell the scanf that any white space characters (including the newline '\n') left on stdin should be ignored.
In your second case, it's not looking for 2 numbers, it's looking for a number and a white space character. scanf(" %d ", &a) says "ignore any white space, then look for a decimal number, then look for white space". However once the variable (a) is filled it stops reading, because this is how scanf works:
A directive composed of one or more white-space characters shall be executed by reading input until no more valid input can be read, or up to the first byte which is not a white-space character, which remains unread.
So it's not really looking for another number, you can type anything at this point and it will be happy because it's just looking for another white space character to be input. So this:
scanf(" %d ", &a);
could be satisfied by this input:
>> 5
f
First the "%d" matches the 5, then the newline following the f matches the " "

Why we need to put space before %c? [duplicate]

This question already has answers here:
What does space in scanf mean? [duplicate]
(6 answers)
Closed 7 years ago.
The following code gives the bizarre o/p as soon as I compile it.
main() {
char name[3];
float price[3];
int pages[3], i;
printf ( "\nEnter names, prices and no. of pages of 3 books\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
scanf ("%c %f %d", &name[i], &price[i], &pages[i] );
printf ( "\nAnd this is what you entered\n" ) ;
for ( i = 0 ; i <= 2 ; i++ )
printf ( "%c %f %d\n", name[i], price[i], pages[i] );
}
But if we give the space in the scanf statement before %c, it gives proper o/p.
Can anyone please explain me why is it so?
Update:-
If I am providing the input like this-
F
123.45
56
J
134
67
K
145
98
then my question is why not we are giving space before %f and space before %d? Why we need to give space before %c only?
Adding the space to the format string enables scanf to consume the newline character from the input that happens everytime you press return. Without the space, name[i] will receive the char '\n', and the real char is left to be misinterpreted by %f.
So, say your input is
a 1.0 2
b 3.0 4
c 5.0 6
The program sees it more like this:
a 1.0 2\nb 3.0 4\nc 5.0 6\n\377
That is, the line-breaks are actual characters in the file (and the \377 here indicates "end of file").
The first scanf will appear to work fine, consuming a char, a float, and an integer. But it leaves the input like this:
\nb 3.0 4\nc 5.0 6\n\377
So the second scanf will read the '\n' as its %c, unless you get rid of it first.
Adding the space to the format string instructs scanf to discard any whitespace characters (any of space ' ', tab '\t', or newline '\n').
A directive is one of the following:
A sequence of white-space characters (space, tab, newline, etc.; see isspace(3)). This directive matches any amount of white space, including none, in the input.
...
from http://linux.die.net/man/3/scanf
This sort of problem arises whenever you use scanf with %c in a loop. Because, assuming free-form input, newlines can happen anywhere. So, it's common to try to avoid the whole issue by using a two-tiered approach. You read lines of input into a buffer (using fgets); chop-off the silly newline characters; then use sscanf instead of scanf to read from the buffer (string) instead of straight from the file.
Incorrect input using %c
Consider the following snippet of code:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("%c", &y);
printf("%d %c", x, y);
}
Behavior: When you run the above program, the first scanf is called
which will wait for you to enter a decimal number. Say you enter
12(That’s ASCII ‘1’ and ASCII ‘2’). Then you hit the "enter" key to
signal the end of the input. Next the program will execute the second
scanf, except you will notice that the program doesn't wait for you to
input a character and instead goes right ahead to output 12 followed
by a ‘\n’.
Explanation:Why does that happen? Let’s look at the behavior of the
program step-bystep.
Initially there is nothing in the buffer. When the first scanf() is called, it has nothing
to read, and so it waits. It keeps waiting until you type 1,2, then "enter". Now what's in
the buffer are the character 1, the character 2, and the character ‘\n’. Remember that ‘\n’
signifies the end of input, once all fields have been entered, but it is also stored in the
buffer as an ASCII character. At this point scanf will read the largest decimal input from
the buffer and convert that to an integer. In this example, it finds the string "12" and
converts it to the decimal value twelve and puts it in x. Then scanf returns control back to
the main function and returns the value 1, for being able to convert one entry
successfully. In our example, we do not catch the return value of the scanf in a variable.
For robust code, it is important to check the return value of scanf( ) to make sure that the
user inputted the correct data.
What is now left in the buffer is ‘\n’. Next, the second scanf is
called and it's expecting a character. Since the buffer already has
the ‘\n’ character in it, scanf sees that, takes it from the buffer,
and puts it in y. That's why when you execute the printf afterwards,
12 and “enter” are printed to the screen.
Solution: Moral of the story is, enter is a character like any other,
and is inputted to the buffer, and consumed from the buffer by %c just
like any other ASCII character. To fix this, try using this code
instead:
int main( ){
int x;
char y;
scanf("%d", &x);
scanf("\n%c", &y); /* note the \n !! */
printf("%d %c", x, y);
}
**
How does this fix the problem?
** So you again type ‘1’,’2’,’\n’. The first scanf reads "1" and "2", converts that to the decimal twelve and leaves the ‘\n’ in the buffer.
The next scanf now expects a ‘\n’ at the beginning of the next input.
It finds the ‘\n’ in the buffer, reads it, and discards it. Now the
buffer is empty and scanf is waiting on the user to input a character.
Say the user inputs ‘c’, followed by the enter key. ‘c’ is now
assigned to y, NOT "enter". Therefore printf will output "12 c" to the
screen. NOTE: there is again a ‘\n’ sitting in the queue now. So if
you need to do another scanf for a single character, you will have to
"consume" that '\n' before taking another character in from the user.
This is not an issue for any other format specifier, as they all ignore white spaces before
the input.

Resources