因为scanf默认是以空白符(空格、制表符、换行等等)为结束标志的
当遇到空白符是就会结束一次输入,如果需要读取空格的话可以使用gets或者getchar

scanf("%[^\n]",str);
非换行符的都匹配

scanf("%*[^\n]%*c");

%*[^\n]将逐个读取缓冲区中的 '\n' 字符之前的其它字符,% 后面的 * 表示将读取的这些字符丢弃,
遇到 '\n' 字符时便停止读取。此时,缓冲区中尚有一个 '\n' 字符遗留,所以后面的%*c将读取并丢弃这个遗留的换行符,
这里的星号和前面的星号作用相同。由于所有从键盘的输入都是以回车结束的,
而回车会产生一个 '\n' 字符,所以将 '\n' 连同它之前的字符全部读取并丢弃之后,也就相当于清除了输入缓冲区

[root@web c]# cat test.c
#include <stdio.h>
#include <string.h>

int main(){
        char s[100]="";
        char s1[100]="";
        scanf("%[a-z]",s);
        scanf("%s",s1);
        printf("s=%s\r\n",s);
        printf("s1=%s\r\n",s1);
}
[root@web c]# ./test
abc123(输入后回车)
s=abc
s1=123
分析:[a-z]表示匹配小写字母 ,输入abc123 匹配到123时将abc赋值给s,第一个scanf匹配结束,同时将abc从缓冲区中删除,
    执行到第二个 scanf() 时,缓冲区中有数据(123),会直接读取,赋值给s1,同时将123从缓冲区中删除
[root@web c]# ./test
abc def(输入后回车)
s=abc
s1=def
分析:输入abc def第一个scanf匹配abc后遇到空格 结束匹配 将abc赋值给s,同时将abc从缓冲区中删除, 执行到第二个scanf同上
[root@web c]# ./test
123abc(输入后回车)
s=
s1=123abc
分析:输入123abc ,到缓冲区,第一个scanf从缓存中读取数据发现不是字符,匹配失败,缓冲区内容不变,第二个scanf读取缓存区内容 同上
[root@web c]# ./test
123 abc(输入后回车)
s=
s1=123
分析:输入123 abc到缓冲区,第一个scanf从缓冲中开始匹配读取,第一个scanf按照规则读取,匹配失败,到第二个scanf从缓冲区读取123 abc 读取到空格结束

 

scanf:当遇到回车,空格和tab键会自动在字符串后面添加'\0',但是回车,空格和tab键仍会留在输入的缓冲区中
gets:可接受回车键之前输入的所有字符,并用'\n'替代 '\0'.回车键不会留在输入缓冲区中

gets() 用到读取字符串,用回车结束输入
scanf()可以读取所有类型的变量

//scanf.c
#include <stdio.h>
int main(){
    char str1[30], str2[30];
    gets(str1);
    scanf("%s", str2);
    printf("str1= %s  str2=%s\n", str1, str2);
    return 0;
}
[root@centos1 c]# ./scanf
回车
回车
123(回车)
str1=   str2=123
scanf1.c
#include <stdio.h>
int main(){
    char str1[30], str2[30];
    scanf("%s", str1);
    gets(str2);
    printf("str1= %s  str2=%s\n", str1, str2);
    return 0;
}
[root@centos1 c]# ./scanf1
abc(回车)
str1= abc  str2=

 scanf当缓冲区没内容时会等待用户输入,

gets不会,遇到换行就读取结束

scanf("%*c%c",&ch); 接收输入但不赋给任何变量

int main(){
    int i;
    char ch;
    scanf("%d",&i);
    scanf("%*c%c",&ch);
    printf("i=%d,ch=%d\n",i,ch);
}
输入:12ab回车
输出:i=12,ch=98
分析:输入12ab,scanf从缓冲区匹配数字12,遇到a非数字,将12赋值给i,从缓冲区清楚12,第一个scanf结束,
     第二个scanf从缓冲区读取到ab,由于%*c%c ,抑制符*匹配到一个字符a将其舍弃,将a从缓冲区清楚,继续匹配到b赋值给ch,结束
输入:12 ab回车
输出:i=12,ch=97
分析同上