相信很多新手朋友都在scanf,getchar和gets的使用上产生过困惑,尤其是处理字符和字符串时,博主先前就遇到这样的困惑,但一直都是一知半解,今天终于经过一番折腾弄清了它们的用法和区别,下面我们就详细来看看。
一、书写格式和作用
scanf
char a;
scanf("%c",&a);
/*读入一个字符,注意&不能漏*/
char a[10];
scanf("%s",a);
/*读入一个字符串,注意a是数组名,代表的就是数组的首地址,所以a前面没有&*/
getchar
char c;
c=getchar();
/*读入一个字符*/
getchar();
/*从缓冲区吸收一个字符,至于什么是缓冲区,下文会说到*/
gets
char a[10];
gets(a);
/*读入一个字符串*/
二、缓冲区
在此不具体介绍缓冲区,如果感兴趣可自行上网查看,我们只需要知道:
首先我们从键盘上输入的字符或者字符串是放入内存的缓冲区中的,并且按照先后顺序存储在缓冲区,当我们调用一次scanf或getchar或gets时都是从缓冲区中取出,举个例子,当我们从键盘上依次输入a,s,d,f,回车键,则缓冲区存储如下图(假设输入这些字符之前,缓冲区没有字符,如果有则在a之前靠近出口的位置):
如果我们执行scanf("%c",&b)之前缓冲区存储上述字符,那么scanf是是怎样执行的的?它是从键盘上输入一个字符赋值给b吗?当然不是,因为此时缓冲区中还有字符,scanf从出口读入一个字符,也就是a,此时就把a赋值给了b;同理我们执行b=getchar(),也就是将a赋值给b;执行gets(b),b的值就是asdf。
三、具体细节
以下都是基于缓冲区中无字符
scanf
scanf("%c",&a);
/*从键盘输入一个字符赋值给a,剩下所有字符(包括空格、回车、Tab)存储在缓冲区.注意的是scanf读取单个字符时能读取上述三个字符.*/
scanf("%s",a);
/*从键盘上输入一个字符串赋值给数组a,遇到空格、回车、Tab结束,剩下所有字符(包括空格、回车、Tab)存储在缓冲区,并在字符串后自动添加‘\0’作为结束标志.注意的是scanf读取字符串时不能读取上述三个字符.*/
错误展示:
#include<stdio.h>
int main()
{char a,b;
scanf("%c",&a);
scanf("%c",&b);
printf("%c\n",a);
printf("%c\n",b);
return 0;
}
运行结果:
解析:我们从键盘上输入a后按回车,a和回车符都被存储到了缓冲区,a被第一个回车符读取,回车符被第二个scanf读取,因此输出a后换两次行。
getchar
c=getchar();
/*从键盘上输入一个字符赋值给c,剩下所有字符(包括空格、换行、Tab)存储在缓冲区.注意的是getchar能读取上述三个字符,因此常用getchar()吸收回车符.解决上述scanf错误展示,我们就可以在两个scanf之间加上getchar()吸收回车符避免上述错误.*/
gets
gets(a);
/*从键盘上输入字符串赋值给数组a,遇到回车结束,并在字符串后自动添加‘\0’作为结束标志.注意的是gets能读取空格、Tab,但不能读取回车符.*/
以上就是全部scanf,getchar和gets的用法和区别。ps:以上是博主的个人理解,如有错误,欢迎指出。如有帮助,感谢点赞。
另外我觉得对于新手朋友要想真正理解上述内容,还得自己动手不断改写程序通过比较运行结果来感受。比如我就是通过以下程序知道gets是不能读取回车符的:
#include<stdio.h>
int main()
{char a[10];
char b;
scanf("%c",&b);
gets(a);
printf("%s",a);
return 0;
}
运行结果