%[ 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.