浅谈C语言中scanf(),gets()函数区别与联系
int main() { char a[20]; char b[20]; char c[20]; printf("请输入a字符串\n"); scanf("%s",&a); printf("请输入b字符串\n"); gets(b); printf("请输入c字符串\n"); gets(c); return 0; }
【分析】程序本意是输入三个字符串,之所以用printf提示输入是因为想更清楚地看清程序怎么运作的,可以从运行界面看到程序提示输入a字符串和c字符串,但是会越过b字符串不让输入。这里会让人感到困惑。
因为scanf函数在读取字符串时,遇到回车、空格、制表符不会进行读取或转换,会舍弃掉它们以及它们后面的字符至缓冲区,最后在读取的字符后面加上‘\0’.因此到了gets(b)的时候就会读取缓冲区剩下的东西以及最后的换行符就结束了,所以程序不会提示输入b字符串,但是从监视可以看到b中其实是读取了字符串的。然后缓冲区无剩余字符gets(c)可以实现输入c字符串。而且从这个程序也可以体现出来需要用到里面有空格的字符串的时候可以用gets函数。
这里还有一个注意点:在gets(c)读取从键盘输入的字符以及最后需要将缓冲区的数据刷新出去的回车符。它和scanf不同的是不会舍弃回车符至缓冲区中, 而是会丢弃换行符将其改为字符串结束标志‘\0’。所以我们一般喜欢使用这种带有清理收尾工作的输入函数。
最后一个点,我们可以看到b字符串其实读取的是缓冲区中的垃圾数据。因此,为了避免输入流缓冲区中垃圾数据对后续读入的影响,需要清空缓冲区。
下面就介绍方法(不同平台)
c标准规定 fflush()函数是用来刷新输出(stdout)缓存的。对于输入(stdin),它是没有定义的。但是有些编译器也定义了 fflush( stdin )的实现,比如微软的vc。其它编译器是否也定义了 fflush( stdin )的实现应当查找它的手册。gcc编译器没有定义它的实现,所以不能使用 fflush( stdin )来刷新输入缓存。
对于没有定义 fflush( stdin )的编译器,可以使用 fgets()函数来代替它(比用 getchar()、scanf()等函数通用性好)。可以这样忽略输入流中留下的回车等其它输入,从而使下一次的输入总保持一个“干净”的状态。(这个是任何平台下都可以的)
scanf函数读取字符
int main() { char ch1; char ch2; char ch3; char ch4; scanf("%c",&ch1); scanf("%c",&ch2); scanf("%c",&ch3); scanf("%c",&ch4); return 0; }
【分析】用户输入'h'和' '和两个回车符,在监视中可以看到,四个字符如愿以偿得到了用户输入操作的四个字符,也并没有舍弃回车符到缓冲区。