首先我们来看一个例子,代码如下:
int main()
{
char str[50],ch1[50];
scanf("%s",ch1);
gets(str);
printf("ch1的值为:");
puts(ch1);
printf("str的值为:");
puts(str);
printf("输出完毕\n");
return 0;
}
代码很简单就是分别输入两个字符串然后分别输出。但如果我们只输入hello
,然后就回车,就会发现程序结束,输出结果如下:
从输出结果我们可以看出,scanf函数接收的输入值为hello
,gets函数接收的输入值为空(注意gets函数的输入值不是回车换行,因为puts函数会自带一个回车换行),这是为什么呢?我的本意是换行后接着输入第二个字符串,怎么就结束了。
下面我们梳理一下这个输入的流程就应该明白了为什么会导致这个结果。首先我们在终端输入字符时,这些字符是保存到缓冲区的,然后在我们按下回车时字符才进入标准输入流中,等待scanf
、gets
这些输入函数读取,并且回车换行符也进入了标准输入流中。首先就是scanf
函数读取字符,scanf
函数遇见空格、制表符以及换行符这些空白字符时就会结束读取,所以scanf
函数在读到换行符时就认为输入结束,换行符继续留在标准输入流中,故它的输入值为hello
。然后就是gets
函数开始执行,gets
函数发现标准输入流中还有未读取的字符,故继续在标准输入流中读取字符,但它读到的第一个字符就是回车换行符,而gets
函数输入结束的标志就是回车换行符,所以它在读第一个字符时就停止读取,函数结束返回,故它的输入值为空。并且gets
函数会将标准输入流清空。再次调用输入函数,需要在终端重新输入。
总结一下,造成这样的原因就在于scanf
函数的输入结束符是空白字符,也就是空格、制表符、和换行符这些,而gets
函数的输入结束符是回车换行符。因为gets
函数所读取的第一个字符就是回车换行符,所以gets
函数的输入内容为空。
另外值得注意的就是用scanf
函数输入字符串时,它是从第一个非空白字符开始读取,而gets
函数无这个特性。