-1
#include <stdio.h>
#include <string.h>
#include<stdio.h>
int main()
{
   int ch;
   char str;
   scanf("%d", &ch);
   scanf("%c", &str);
   printf("x = %d, str = %c", ch, str);
   return 0;
}

Input: 10(enter)
Output: x = 10, str =

here in this code scanf("%d", &ch); reads an integer and leaves a newline character in buffer. So scanf("%c", &str); only reads a newline character. Which i understood.

But when i run this code:

#include <stdio.h>
#include <string.h>
#include<stdio.h>
int main()
{
   int ch;
   char str[54];
   scanf("%d", &ch);
   scanf("%s",str);
   printf("x = %d, str = %s", ch, str);
   return 0;
}

Input: 10(enter) test
Output: x = 10, str = test

here it seems like scanf("%s",str); ignores the newline character from the buffer and reads test from console.

Why this is happening? Give me a proper detailed Explanation

  • Welcome to Stack Overflow. Please take the [tour] to learn how Stack Overflow works and read [ask] on how to improve the quality of your question. [Please do not upload images of code/errors when asking a question.](https://meta.stackoverflow.com/q/285551) – Progman Oct 10 '21 at 19:20
  • It skips the newline *by design*. The `scanf` conversion stops at the first character it cannot convert, which is typically (but not necessarily) a space or a newline, and that character remains in the input buffer. It will be read by the *next* `scanf()`. Format specifiers `%d` and `%s` and `%f` automatically filter such leading whitespace characters, but `%c` and `%[]` and `%n` do not. You can instruct `scanf` to do so by adding a space just before the `%`. – Weather Vane Oct 10 '21 at 19:58
  • Most `scanf` format characters skip leading whitespace *before* they parse. And all `scanf` format characters leave trailing whitespace (like the newline `\n`) after they parse. So usually the trailing `\n` gets taken care of by the next `scanf` call. But unlike the others, `"%c"` does *not* skip leading whitespace — so it'll take that trailing `\n` from the previous call as the character it reads. If you want `"%c"` to act like the others, you can put in an explicit space, like this: `" %c"`. – Steve Summit Oct 10 '21 at 20:33

2 Answers2

1

Why this is happening?

That is what %s is specified to do in scanf. In the 2018 C standard, clause 7.21.6.2, paragraphs 7 and 8 say:

… A conversion specification is executed in the following steps:

Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.

So, all the conversions except %[, %c, and %n skip initial white-space characters, which includes new-line characters.

Generally, scanf is not intended to be a full-power parser that facilitates examining every character in the input stream. It is intended to be a convenience mechanism, for reading simple data formats without a lot of rigid constraints. Skipping white-space is part of that.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
-1

"test" it's not ignored, the problem is that you're requesting an int (read only numbers), and then a string (read until \n or space, without reading those).

int ch;
char str[100];
scanf("%d", &ch); // this will read "10" and leave "\ntest\n" on the buffer
scanf("%s", str); // this will read "", so it will ask to the user an input. ("\ntest\n" is still on the buffer)

What you want is this:

int ch;
char str[100];
scanf("%d", &ch); // this will read "10" and leave "\ntest\n" on the buffer
scanf("%c", &str[0]); // this will read "\n" and leave "test\n" on the buffer
scanf("%s", str); // this will read "test" and leave "\n" on the buffer
  • 1
    Your answer is wrong. The `scanf("%s", str);` in your first snippet will skip all leading whitespace in the input buffer ... *including* the newline left over from the previous read. It's the `%c` format in the OP's first code snippet that doesn't skip that hanging newline. – Adrian Mole Oct 10 '21 at 19:51
  • @AdrianMole can u please explain it more. – Paras Mittal Oct 10 '21 at 19:58
  • 1
    In the first code block the comment `// this will read "\n"` is incorrect. It is *impossible* to read a newline (or an 'empty' string) with the `"%s"` format specifier, because it filters all leading whitespace, and terminates at the first whitespace. If you just press the Enter key in response, the system will wait until you enter at least one non-whitespace character. – Weather Vane Oct 10 '21 at 20:11
  • They're right, %s read until a space or \n (without including those). I probably think about `fgets`. – Roger Miranda Perez Oct 10 '21 at 20:18
  • @ParasMittal Just read the first paragraph of the first answer to the question I suggested as a duplicate. – Adrian Mole Oct 10 '21 at 20:18
  • 1
    The edit is still incorrect. It is impossible to read an 'empty string' with `%s`. – Weather Vane Oct 10 '21 at 20:22