Using% [^ \ n]
scanf()
"%["
The conversion specifier runs what's called a "scanset". It bears some similarities to the regex construct, which looks the same (but is still very different). This standard says:
Matches a non-empty sequence of characters from the set of expected characters (scan).
...
The conversion specifier includes all subsequent characters in the format string, up to a matching right parenthesis (]. Characters between the parentheses (scan list) constitute a scan, unless the character after the left parenthesis is bypass (^), in which case the scan contains all characters, which do not appear in the scan list between round and right brackets.If the conversion specifier begins with [] or [^], the right bracket character is in the scan list, and the next next right bracket character is a matching right parenthesis that ends the specification; otherwise the first next character of the right parenthesis is the one that ends the specification.If a-character is in the scan list and is not the first, or the second, where the first character is the ^ or the last character,behavior is implementation-defined.
So, the conversion scanf()
"%[\n]"
will match a newline character, but "%[^\n]"
will match all characters up to a newline.
Here's what P.J. Plager has to say about scanning in the "Standard C Library":
A scan set behaves the same as a conversion specifier
s
. It stores charactersw
(defaults to the rest of the input) in the char array it points toptr
. It always preserves the null character after any input. It doesn't miss the leading white space. It also allows you to specify which characters should be treated as part of the field. You can specify all characters that match, as in%[0123456789abcdefABCDEF]
, which matches an arbitrary sequence of hexadecimal digits. Or you can specify all characters that do not match, as in%[^0123456789]
, which matches any characters other than numbers.If you want to include a right parenthesis (
]
) in a set of given characters, write it immediately after opening[
(or[^
), as in%[][]
that scans for square brackets, you cannot include a null character in the set of characters you specify. Some implementations may indicate a range of characters using the minus sign (-
). For example, a list of hexadecimal digits can be written as,%[0-9abcdefABCDEF]
or even, in some cases, as%[0-9a-fA-F]
. Note, however, that this usage is not universal. Avoid it in a program you want to keep as portable as possible.
a source to share
Yes, this is very similar to a set in a regex - you can specify a character set to accept or a character set to complete a scan, so "% [^ \ r \ n \ t]" will read until it encounters a space, returning caret, newline, or tab. As with RE, the leading "^" means "no" - you can omit it to indicate which characters will be accepted instead of which will complete the conversion. With most compilers (although not technically required) you can specify ranges such as "% [az]" to specify any lowercase letter (in this case, when "-" is not the first or last character, the behavior is implementation-defined) ...
Although not widely used (or even known), this conversion has been part of C almost forever and is supported in C89 / 90.
a source to share