%[
matches any character found in its set of characters. ]
terminates the set.
- For example, with the input
hello world
, %[ehlo]
matches hello
, stopping when it encounters the space which is not found in the set.
Starting that set with ^
inverts the match, matching any character not found in the set.
The effect: %[^\n]
matches as many characters as it can, that are not the newline character.
%c
matches any character. Adding *
, as in %*c
, prevents scanf
from assigning that character to any variable.
The overall effect is that "%[^\n]%*c"
reads as many characters as it can, storing those characters in a buffer until it reaches a newline character. It then consumes and discards the newline. Effectively, it reads a line of text.
Note that not specifying a maximum field-width when using %[
(or %s
) leaves your program open to buffer overflows (same problem as using gets()
).
To avoid potentially undefined behaviour, you should always provide the maximum number of characters to be read
char c[50];
scanf("%49[^\n]%*c", c);
which should be at most the size of the buffer minus one (to leave room for the null-terminating byte, '\0'
).
In this particular example, you will experience data loss if the string entered is longer than 49 characters, as %*c
will consume something other than the newline.
For these reasons, it is generally advisable to instead use fgets
when you want to read a line of text, as you can more easily detect oversized lines.