12
#include <stdio.h>
int main(int argc, char* argv[]) {
  char c;
  scanf(" %c", &c);
  printf("%c\n", c);
  return 0;
}

[root@test]# ./scanf 
a
a

[root@test]# ./scanf 
 h
h

It seems always matching whether space exists,why?

osgx
  • 90,338
  • 53
  • 357
  • 513
Je Rog
  • 5,675
  • 8
  • 39
  • 47
  • 1
    http://linux.die.net/man/3/scanf, http://www.manpagez.com/man/3/scanf/, http://unixhelp.ed.ac.uk/CGI/man-cgi?scanf+3, GIYF – sehe Jul 05 '11 at 12:11

6 Answers6

10

White space (such as blanks, tabs, or newlines) in the format string match any amount of white space, including none, in the input.

http://www.manpagez.com/man/3/scanf/

Vinicius Kamakura
  • 7,665
  • 1
  • 29
  • 43
  • 1
    @Je Rog: It doesn't match "keys". It matches input *characters*. And newline character is considered whitespace, so yes, it will skip the newline character. – AnT stands with Russia Jul 05 '11 at 12:12
  • Yes, space can be used to match "newline". Be careful, in Windows when you hit RETURN, it usually sends "\r\n" and in Linux only "\n". But for simple numeric input scan, that usually doesn't matter because the number conversion will stop as soon as it hits a non-digit (`.` `-` and `+` are allowed depending on the type of input you are scanning) – Vinicius Kamakura Jul 05 '11 at 12:13
  • Aren't both of `\r` and `\n` whitespace,why do I need to be careful? – Je Rog Jul 05 '11 at 12:15
  • 2
    @hexa: `fscanf` is used with text streams. In text streams it doesn't matter whether it is Linux or Windows, since text stream automatically converts platform-specific end-of-line marker to a single `'\n'` on any platform before it gets a chance to get to `fscanf`. – AnT stands with Russia Jul 05 '11 at 12:16
  • It is just a caveat to be aware of when dealing with user input. It won't matter much in that case. – Vinicius Kamakura Jul 05 '11 at 12:17
  • @Je Rog: You don't need to worry about `\r` and `\n`, since your `scanf` will never see it even on Windows (as long as you are using it properly, i.e. with a *text* stream). – AnT stands with Russia Jul 05 '11 at 12:17
  • @AndreyT I did not know that :) But now I recall only having that type of problem with `getchar()` and the like – Vinicius Kamakura Jul 05 '11 at 12:18
  • @AndreyT ,do you mean `scanf` in internally implemented with `fscanf`? – Je Rog Jul 05 '11 at 12:18
  • @Je Rog: Well, it can be implemented in many ways, but functionally `scanf(...)` is indeed equivalent to `fscanf(stdin, ...)`. That's actually how it is defined in the standard. And `stdin` is a text stream, BTW. – AnT stands with Russia Jul 05 '11 at 12:23
7

Space in scanf format means "skip all whitespace" from the current position on. Since most scanf format specifier will already skip all whitespace before attempting to read anything, space is not used in scanf format most of the time. However, when you are using a format specifier that does not ignore whitespace, including space into the format when necessary (to force the skip) might make sense.

The specifiers that do not ignore whitespace are c [ and n. So, specifying a space in front of one of those specifiers makes a difference. Otherwise, it doesn't make any difference. In your specific example, the whitespace is ignored specifically because you used a space in your scanf format (since your are using %c). Try removing the space and see what happens.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
4

A whitespace character in the format string will ignore 0 or more whitespace characters from the input, until the first non-whitespace character.

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
1

The documentation for scanf says:

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.

And also

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

Which means the space in your format string is needed. If you were going to read an integer, however, the space would have been redundant:

/* equivalent statements */
scanf(" %d %d %d", &v1, &v2, &v3);
scanf("%d%d%d", &v1, &v2, &v3);
pmg
  • 106,608
  • 13
  • 126
  • 198
1

The %c will not skip whitespace char as numeric format specifiers do. So if you use :

#include<stdio.h>
int main(int argc, char* argv[]){
  char c;
  scanf("%c", &c);
  printf("%c\n", c);
  scanf("%c", &c); // Try running with and without space
  printf("%c\n", c);
  return 0;
}

It is very likely that the previous whitespace character in the input buffer will be taken in the second scanf, and you will not get a chance to type. The space before %c will make scanf skip whatever whitespace character is there in the input buffer so that you will be able to enter your input properly. Sometimes to get the same effect people write:

fflush(stdin);
scanf("%c" &c);

But this is considered very bad programming as C Standard specifies the behavior of fflush(stdin) is undefined. So always use space in the format string unless you have a specific reason to capture whitespacesas well.

Codebuddy
  • 11
  • 2
0

The space just means that a space is accepted as input. You might want to read this related thread on the dangers of using scanf rather than fgets.

How do you allow spaces to be entered using scanf?

Community
  • 1
  • 1
Roger
  • 15,793
  • 4
  • 51
  • 73