% [^ \ n] s in scanf does not wait for input and is skipped

In the loop in the code below, scanf("%[^\n]s",array) does not work. It does not wait for input and is skipped. But space up to % fixes the problem. Why?

Here is the wrong program:

 #include <string.h> #include <stdio.h> int main() { int t; scanf("%d",&t); while(t--){ char arr[199]; scanf("%[^\n]s",arr); printf("%s",arr); } return 0; } 

Here is the correct code:

 #include <string.h> #include <stdio.h> int main() { int t; scanf("%d",&t); while(t--){ char arr[199]; scanf(" %[^\n]s",arr); printf("%s",arr); } return 0; } 

Why does he need space in front of % in order for it to work as expected?

+5
source share
2 answers

First of all, trailing s not part of the %[ format specifier, so remove it and talk about %[^\n] .

Now, what %[^\n] tells scanf to do is scan everything down to the newline character ( '\n' ) or EOF , whichever comes first, and stores it in the corresponding argument, in this case arr .

And here's the catch: %[^\n] fails if the first character read is \n .

β€œWait,” you say. "I did not go it alone. So, why didn't it work?" True. You do not. But remember the Enter that you pressed for the previous line? It turns out that the previous call to scanf captures everything until \n leaves \n there and returns. So, in the next iteration of the loop, scanf sees this \n character remaining the previous call to scanf , fails and returns 0.

As for space, this is a whitespace character. And the whitespace in scanf tells it to scan and discard all whitespace to the first character without spaces. This way it removes \n (since it is a space character), and scanf will wait for input.

+2
source

In this format, %[^\n] , scanf() stops after reading a new line. Thus, after the first input, a new line appears that is not used. Thus, subsequent calls to scanf () do not read any input at all.

With a space in %[^\n] , scanf() ignores any number of space characters. Therefore, scanf() ignores the remaining lines of the newline. From scanf :

A sequence of space characters (space, tab, newline, etc., see isspace (3)). This directive matches any number of spaces, including none, at the input.

By the way, you do not need extra s at the end of the format string.

Use fgets() , which is usually superior to scanf() ( fgets() will read the new char string into the buffer if there is space). Also see: Why does everyone say not to use scanf? What should i use instead? .

+1
source

Source: https://habr.com/ru/post/1265921/


All Articles