How to use scanf in C?

scanf格式详解

c语言中,你可能会遇到这样的scanf输入形式:scanf("%[^\n]%*c",s);,从而摸不着头脑——这是个什么意思呢?

我们慢慢分析,已知scanf的格式说明符遵循以下原型[1]:

1
%[*][width][length]specifier

%后三个[]中的内容是可选的,可以有,也可以没有。分别表示:

sub-specifier description
* An optional starting asterisk indicates that the data is to be read from the stream but ignored (i.e. it is not stored in the location pointed by an argument).
width Specifies the maximum number of characters to be read in the current reading operation (optional).
length One of hh, h, l, ll, j, z, t, L (optional). This alters the expected type of the storage pointed by the corresponding argument (see below).

其中specifier内容有以下形式:

specifier Description Characters extracted
i Integer Any number of digits, optionally preceded by a sign (+ or -). Decimal digits assumed by default (0-9), but a 0 prefix introduces octal digits (0-7), and 0x hexadecimal digits (0-f). Signed argument.
d or u Decimal integer Any number of decimal digits (0-9), optionally preceded by a sign (+ or -). d is for a signed argument, and u for an unsigned.
o Octal integer Any number of octal digits (0-7), optionally preceded by a sign (+ or -). Unsigned argument.
x Hexadecimal integer Any number of hexadecimal digits (0-9, a-f, A-F), optionally preceded by 0x or 0X, and all optionally preceded by a sign (+ or -). Unsigned argument.
f, e, g Floating point number A series of decimal digits, optionally containing a decimal point, optionally preceeded by a sign (+ or -) and optionally followed by the e or E character and a decimal integer (or some of the other sequences supported by strtod). Implementations complying with C99 also support hexadecimal floating-point format when preceded by 0x or 0X.
a
c Character The next character. If a width other than 1 is specified, the function reads exactly width characters and stores them in the successive locations of the array passed as argument. No null character is appended at the end.
s String of characters Any number of non-whitespace characters, stopping at the first whitespace character found. A terminating null character is automatically added at the end of the stored sequence.
p Pointer address A sequence of characters representing a pointer. The particular format used depends on the system and library implementation, but it is the same as the one used to format %p in fprintf.
[ characters ] Scanset Any number of the characters specified between the brackets. A dash (-) that is not the first character may produce non-portable behavior in some library implementations.
[^ characters ] Negated scanset Any number of characters none of them specified as characters between the brackets.
n Count No input is consumed. The number of characters read so far from stdin is stored in the pointed location.
% % A % followed by another % matches a single %.

我们前面例子中的[^\n]就符合其中[^ characters ]一栏,表示读入除了换行符\n以外的任何字符。

所以%[^\n]表示读入除了\n以外任意字符,但是没有读入最后输入的\n,而%*c的作用是读入这个\n并且遗弃(*)。

参考资料

[1] scanf

[2] What does scanf("%*[^\n]%*c") mean?

[3] What does %[^\n] mean in C?