因为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 分析同上