引言

正常情况下,scanf 会跳过空白读入且遇到空白读入会停止,即遇到形如 abc def 这种输入时,如果我们仅仅使用 scanf("%s", str) 这种输入格式,只能读到前面的 abc ,如果我们想读入整行,只能采用 get 函数来解决。

现在,我们引入关于 scanf 的正则表达式用法,来完成之前无法完成的一些任务。

正则用法

1
scanf("%[^\n]", str);
  1. ^ 表示逻辑运算符 “非”, [^\n] 表示遇到换行字符就结束读入。

我们都知道, scanf 是无法接受空白符的,一旦接收到空格就停止读入(%c 用法除外),我们可以用这种方式来读取一行;

  1. * 表示把该输入项读入后舍去,不存入任何变量中,所以我们可以使用 scanf("%[^\n]%*c", str); 这种用法来读取一行变量,并吸掉末尾的换行符。

举例

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
int main(void)
{
char s[100], s1[100], s2[100];
scanf("%[^\n]%*c", s); // 读入一行,并吸掉末尾换行符
scanf("%[^#]", s1); // 遇到 '#' 才会停止读入,会读到空白符
scanf("%*[^\n]%*c"); // 吸掉 '#'以及后面的'\n'
printf("%s\n", s);
printf("%s\n", s1);

return 0;
}
1
2
3
4
//input
abcdefg
edfghjj
#
1
2
3
4
//output
abcdefg
edfghjj

我们观察一下输入,一共有三行,其中前两行都是字符串,第三行是一个 #,用来作为结束符。

然后代码中的第一个 scanf 会读入第一行的字符串(并吸掉末尾的换行符),第二个 scanf 会一直读入,包括读到第二行末尾的换行符,直到遇到 # 才会停止(并不会读入 # ),第三个 scanf 会读入第三行,并吸掉末尾的换行符。

所以最后输出是三行(第三行是因为第二个 scanf 读取了换行符)。