10

Consider the following C code snippet:

#include <stdio.h>

int main()
{
    int a;
    char c;
    scanf("%d",&a);
    scanf("%c",&c);
    printf("int=%d\n",a);
    printf("char=%c\n",c);
}

I'm able to input only the integer and not the character.The output is simply the integer value and no value is output for the second printf statement.

However if I use a space before the format specifier:

scanf(" %c",&c);

It works as expected. Why is this the case?

Someone told me it has something to do with clearing the input buffer. Could someone shed some light on the same?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
passmaster10
  • 127
  • 1
  • 2
  • 7

3 Answers3

10

The difference between scanf("%c", &c1) and scanf(" %c", &c2) is that the format without the blank reads the next character, even if it is white space, whereas the one with the blank skips white space (including newlines) and reads the next character that is not white space.

In a scanf() format, a blank, tab or newline means 'skip white space if there is any to skip'. It does not directly 'clear the input buffer', but it does eat any white space which looks similar to clearing the input buffer (but is quite distinct from that). If you're on Windows, using fflush(stdin) clears the input buffer (of white space and non-white space characters); on Unix and according to the C standard, fflush(stdin) is undefined behaviour.

Incidentally, if you typed the integer followed immediately by a carriage return, the output of your program ends with two newlines: the first was in c and the second in the format string. Thus, you might have seen:

$ ./your_program
123
int=123
char=

$

That is, the scanf() reads the newline as its input. Consider an alternative input:

$ ./your_program
123xyz
int=123
char=x
$

The integer input stopped when it read the 'x'; the character input therefore reads the 'x'.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Can You Tell difference between clearing and skipping the buffer, i am quite confuse here? – Suraj Jain Feb 27 '17 at 10:12
  • The difference is the spelling — the five characters before the 'ing'. There isn't a defined meaning for 'clearing' or 'skipping'. I guess that if I was to choose a meaning, 'clearing' would involve the programmer in some explicit work, whereas 'skipping' happens inside the `scanf()`-family function without any explicit work by the programmer, but that's open for discussion and other people might have legitimate alternative definitions that would work coherently too. – Jonathan Leffler Feb 27 '17 at 15:20
2

Because after you input the number and press ENTER, the new line stays in the buffer and will be processed by the second scanf.

In short, you saved new line in the variable c.

However ,if you use

scanf(" %c",&c);
//     ^

the space will consume the new line, which makes c the value you expected.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
-1

You have to pass a pointer to the data object specified by the format string, so

scanf("%c", c);

will actually pass the value of c, which in turn could cause a program fault,

scanf("%c", &c);

will pass the address of c, allowing scanf to change the value of your copy.

The space after the %c will force it to look for a character, AND THEN a space. If there is not a space, it will not read the character

phyrrus9
  • 1,441
  • 11
  • 26
  • 1
    This doesn't even attempt answer the question why space makes `scanf` work correctly. In addition to that, nowhere in the question does the OP propose the use of `scanf("%c", c)`. – user4815162342 Aug 28 '13 at 15:29
  • Also, a trailing space in a format string is a minor disaster, at least for an interactive program; it is not satisfied until it reads, and then pushes back, a non-white space character. So, you might enter 'x' and return, but the `scanf("%c ", &c)` won't return until you type something other than a space or tab. – Jonathan Leffler Aug 28 '13 at 16:59