arguments of a scanf statement - c

I wrote this code:
scanf("%d \n", &n);
for(i=0;i<n;i++)
printf("%d \n",i);
It was not printing. I realised that there was a '\n' in the call to scanf. When I removed that I got the expected output. Why was it not giving the output when the scanf format string contained a '\n'?
What is the reason?

scanf has an implicit read to end of line. Since you had a '\n' in your format string, it was reading your first return as part of the format. It was then continueing to wait for the '\n' it expected as a terminator. If you provided another token, followed by a return, then you would get the expected results.
So, if you supplied:
2
7
You would get the output:
0
1
Because, the first number (2), has been matched against your first format specifier. What I'm unsure about is why you need to provide another token (just pressing return on the subsequent line doesn't work). I assume that's because scanf requires a minimum of one non-white space character, but I could be wrong.

Related

C printf wont print before scaning next number

I got this piece of code
#include<stdio.h>
#include <stdlib.h>
int main()
{
int i;
int number, S;
float MO;
S = 0;
for(i=0;i<10;i++)
{
printf("AAA %d\n", i );
scanf("%d\n", &number);
S = S + number;
}
MO = S/10;
printf("%d , %f \n",S , MO );
return 0;
}
when the execution starts, AAA 0 is printed.I then give my first number.After that, i am expecting to see AAA 1 , but this will be printed only after i give my second number.
Checked this here
C/C++ printf() before scanf() issue
but seems i can get none of these solutions work for me
The answers claiming that this has something to do with flushing input or output are wrong. The problem has nothing to do with this. The appearance of the \n character at the end of the scanf() template string instructs scanf() to match and discard whitespace characters. It will do so until a non-whitespace character is encountered, or end-of-file is reached. The relevant part of the C11 Standard is §7.21.6.2 5:
A directive composed of white-space character(s) is executed by
reading input up to the first non-white-space character (which remains
unread), or until no more characters can be read. The directive never
fails.
In OP's case, a second number must be placed in the input stream so that the first can be assigned. The second number then remains in the input stream until the next call to scanf(). In the case of the example given by Stephan Lechner, taking input from a file, there is a number in the input stream after each number to be assigned, until the last number (if there are exactly ten numbers), and then the EOF causes scanf() to return. Note that OP could also have signalled EOF from the keyboard after each input. Or, OP could enter all numbers on one line, with an extra number to signal end of input:
1 2 3 4 5 6 7 8 9 10 11
The solution is simply to remove the \n from the end of the scanf() template string. Whitespace characters at the end of such a template string are tricky, and almost never what is actually desired.
Just remove the \n from the scanf format string:
scanf("%d", &number);
"\n" waits for non-white-space. Instead use scanf("%d", &number) #Michael Walz and check its return value.
Let us break down scanf("%d\n", &number);
"%d" Scan for numeric text. This specifier will allow leading white-space. Once some non-numeric character is found, put that character back into stdin. If valid numeric text for an integer was found, convert to an int and save to number.
"\n" Scan and discard 0 or more white-spaces such as '\n', ' ', and others. Continue scanning until non-white-space is encountered, put that character back into stdin.
Now return the number of fields scanned (1).
Notice step 2. User had to type in data after the Return or '\n' to get scanf() to return.
The issue is with the buffering of stdout which doesn't force a flush unless a \n is in the output or fflush is called specifically

Break out of loop (do/while) by pressing a button [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.

switch with scanf one more input

I'd like to ask, if somebody can help me with the problem I have in my code. I mean while I want scanf 2 variables, code want one more input.. dunno whats wrong..
btw: I add part of the code
for(i;i<4;i++){
switch(i){
case 0:{
printf("Bod #1:\n");
scanf("%d%d\n",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 1\n");
}
break;
Your problem lies with this line:
scanf ("%d%d\n", &x1, &y1);
specifically the \n in the format string. Referencing the standard (C11 7.21.6.2 The fscanf function /5 and keeping in mind that \n is a white-space character:
A directive composed of white-space character(s) is executed by reading input up to the first non-white-space character (which remains unread), or until no more characters can be read. The directive never fails.
So, as per the input values in your question, scanf starts processing the format string "%d%d\n".
The first format specifier %d needs more input and, when you enter 45\n, it skips any white-space (of which there is none) and loads the integer into its variable, leaving x1 == 45 and the input stream thus (^ represents the next read point):
45\n
^
The second format specifier %d skips white-space (the \n) and then needs more data so you enter 459\n. It then loads that integer into its variable, leaving y1 == 459 and the input stream thus:
45\n459\n
^
Here's where your problem starts. The final format specifier \n needs to read up to but not including the first non-white-space character. But it cannot tell that there's a non-white-space character at this point (since you may enter some more white-space), so it again needs more input which you provide: 54\n. This leaves the input stream as:
45\n459\n54\n
^
So now, the \n format specifier knows that the 5 in 54 is the first non-white-space character and it stops before reading that, giving:
45\n459\n54\n
^
That's the point at which scanf() returns since all format specifiers have been satisfied. Of course, the next call to scanf("%d%d...") will already have 54\n in the input stream so that will be used to populate x1. You'll still have to enter two more values before scanf() returns, the first which will populate y1 and the second which will satisfy the \n specifier.
Now, how to fix it. Well, that's pretty easy. As alluded to above, %d (and most other format strings) skip white-space before they attempt to read their data.
That means newlines will be automatically ignored if you just use "%d%d" as your format string, without the problmatic \n.
See, for example the following code:
#include <stdio.h>
int main (void) {
int x1, y1;
printf("Bod #1:\n");
scanf("%d%d",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 1\n");
printf("\nBod #2:\n");
scanf("%d%d",&x1,&y1);
printf("x1=%d y1=%d\n",x1,y1);
printf("working 2\n");
return 0;
}
and sample run:
Bod #1:
45
459
x1=45 y1=459
working 1
Bod #2:
314159
271828
x1=314159 y1=271828
working 2

Why do interleaved scanf() + printf() statements result in both scanf() calls executing first, then both printf() calls?

Can you please explain one thing in the following code:
#include<stdio.h>
int main()
{
int n;char ch,ch1;
scanf("%d\n",&n);
printf("d-%d \n",n);
scanf("\n%c",&ch);
printf("ch-%d \n",ch);
scanf("\n%c",&ch1);
printf("ch1-%d \n",ch1);
printf("%d %d %d\n",n,ch,ch1);
return 0;
}
Why is it that after entering the value of n,it directly asks for the value of ch and then directly executes the statements to print their respective values ie the statements:
printf("d-%d \n",n);
printf("ch-%d \n",ch);
scanf("%d\n",&n); skips any number of trailing white-spaces (including none) after actual the input. It can also be written asscanf("%d ",&n);.
scanf("\n%c",&ch); skips any number of leading white-spaces (including none) before the actual input. It can also be written as scanf(" %c",&ch);.
NOTE: A white-space in a format specifier is able to skip any number of white-spaces.
Now what does it mean by skipping white-spaces ?
It means scanf repeatedly reads white-space characters from input until it reaches a non-white-space character. Now there is no white-space characters left in the buffer.
When it encounters a non-white-space character, then this character is put back to be read again during the scanning of the next input item or during the next call of scanf.
Now coming to your question.
Why do interleaved scanf() + printf() statements result in both scanf() calls executing first, then both printf() calls?
I am assuming the input for n is 15. When you press Enter key then the \n character goes with 15 in the input buffer. scanf("%d\n",&n); reads the 15 and then skips \n. Now this scanf waits for a non-white-space character to be entered (unlike what you supposed that 15 should be printed) . When you enter a, it puts it back for the next call of scanf. The next statement scanf("\n%c",&ch); reads this a from the buffer and do not let the user to input the value for ch. Since the value of n and ch both is now read by these scanfs, it appears to be that both of
printf("d-%d \n",n);
printf("ch-%d \n",ch);
executes after both of the scanfs call (which is not the case!).
Any whitespace in a scanf format is like any other whitespace in a scanf format. It simply tells scanf to skip any whitespace in the input.
Most format codes doesn't need it though as they skip leading whitespace automatically, but one that does (unless you want to actually read a whitespace character) is the "%c" format code.
You might also want to read this reference.

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