Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is adding a leading space in a scanf format string recommended?

I am currently reading this book "C11 Programming for beginners" and in the scanf() chapter it says:

"Always add a leading space before the first control string character to ensure accurate character input." As in:

scanf(" %s", whatever);

The control string " %s", has a space before it. I know it sounds pretty self-explanatory, but I don't really get what could go wrong, and how this space ensures accurate character input.

like image 456
Stanley Avatar asked Oct 15 '14 20:10

Stanley


People also ask

Why does scanf need space?

Answers. Space before %c removes any white space (blanks, tabs, or newlines). It means %c without space will read white sapce like new line(\n), spaces(' ') or tabs(\t). By adding space before %c, we are skipping this and reading only the char given.

How does scanf treat spaces?

Adding a whitespace character in a scanf() function causes it to read elements and ignore all the whitespaces as much as it can and search for a non-whitespace character to proceed. scanf("%d "); scanf(" %d"); scanf("%d\n"); This is different from scanf("%d"); function.

How do you put a space in a scanf?

So we use “%[^\n]s” instead of “%s”. So to get a line of input with space we can go with scanf(“%[^\n]s”,str);

How does the scanf function work?

The scanf() function reads data from the standard input stream stdin into the locations given by each entry in argument-list . Each argument must be a pointer to a variable with a type that corresponds to a type specifier in format-string .


1 Answers

@WhozCraig well stated shortcomings to this advice. Its comes without rational nor detail. Further it does not apply to "%s" as "%s" consumes leading white-space with or without a leading space.

A leading white-space, be it ' ', '\t', '\n', etc. all do the same thing: direct scanf() to consume and not store optional leading white-space char. This is useful as typical usage of previous scanf() does not consume the user's '\n' from the Enter

scanf("%d", &some_int);
scanf("%c", &some_char);  // some_char is bound to get the value '\n'

All scanf() input specifiers ignore leading spaces, except 3: "%c", "%n", "%[]".

Simple directives do benefit with the leading space as in the following. Previous left-over white-space is consumed before '$'.

int Money;
scanf(" $%d", &Money);

Often, though not always, a leading space before "%c" is beneficial as when reading a single char of user input.

char ch;
scanf(" %c", &ch);

What is most wrong with the advice is that 1) when using "%s", supplying a width parameter is essential to robust code and 2) the return value should be checked.

char buf[30];
int cnt = scanf("%29s", buf);
if (cnt != 1) Handle_NoInput_or_EOF_IOError();

Note that all the conversion specifiers except %c, %[…] (scan sets) and %n skip leading white space automatically, so the advice is not really relevant with %s, or %d or %lf, etc.

Lastly, I recommend using fgets() rather than scanf() whenever one can — which is usually the case.

like image 87
chux - Reinstate Monica Avatar answered Sep 28 '22 16:09

chux - Reinstate Monica