【C语言】最通俗易懂地讲解scanf、gets和getchar的区别(相信我,看了一定懂!!!)
2020-03-02 04:54
2166 查看
欢迎关注WX公众号:【程序员管小亮】
专栏C++学习笔记
声明
1)本文仅供学术交流,非商用。所以部分参考资料并没有详细对应。如果某部分不小心侵犯了大家的利益,还望海涵,并联系博主删除。
2)博主才疏学浅,文中如有不当之处,请各位指出,共同进步,谢谢。
3)此属于第一版本,若有错误,还需继续修正与增删。还望大家多多指点。大家都共享一点点,一起为祖国科研的推进添砖加瓦。
文章目录
〇、写在前面
最近认真钻研了一下,
scanf、
gets和
getchar的区别,发现好多写的博客都很凌乱,看了半天不知所云为何物,决定自己写一个博客记录总结一下。
一、字符
1、scanf(%c)
首先要说的是
scanf,它是格式输入函数,标准格式如下:
int scanf(const char * restrict format,...);
从
标准输入流(stdin)中按照说明的格式读入多个字符,并存入 以输入参数的值为地址的变量 中,所以必须得有
&,除了把字符串读入字符数组中。
为啥?
很简单,因为数组变量名称本身就是特殊的指针,即,数组首元素的地址,故无需使用
&取地址,完事。
举个例子:
char a[10]; scanf("%s",a);
没有
&地址符,程序正常运行。
scanf在遇到
空格符、
回车符(\n)和
制表符(\t)时,都会认为本次输入结束,所有它不能接收
空格符还有
回车符(\n),那么它是如何处理
回车符(\n)的呢?
除了一种特殊情况:
scanf()会忽略行开头的所有空格!!!
scanf对 末尾回车符 的处理是把
回车符(\n)保留在缓存中。
#include<stdio.h> int main(){ char a,ch; int count=0; while(1){ scanf("%c",&a); count++; printf("**************\n"); printf("%d\n",count); } return 0; }
首先输入
a,然后
回车,因为
scanf对 末尾回车符 的处理是把
回车符(\n)保留在缓存中,所以除了
a之外,还有
回车也被读进来了,即,每次蹦两个数字。
这一点和
gets是不同的!!!在后面的
gets中会有详细地介绍。
小结:
不接收
空格,不接收
回车。
2、getchar
接着要说的,是
getchar()函数。
它的作用是从键盘获取且只能获取一个字符。
定义如下:
int getchar(void)
getchar()函数是可以接收
空格的,但是不能接收
回车。即最后的
回车符也不会被接收,
getchar()是会舍弃最后的
回车符的。
回车是干啥用的呢?
因为
getchar函数只能输入字符型,所以在输入时遇到
回车键(\n)才从缓冲区依次提取字符,遇到
空格符不会结束,而是会接收它!!!
下面来看一个例子:
#include<stdio.h> int main(){ char a,ch; int count=0; while((ch=getchar())!='q'){ count++; printf("**************\n"); printf("%d\n",count); } return 0; }
首先确定的一件事是,
getchar是不接收
回车的,所以正常情况下的计数应该是1。
也同样是因为它本身只能接收1个字符,所以这个
回车被留在缓存流中了,而我们这里的程序是遇到
q才停止,故而程序又循环了一下,相当于输入了一个
回车!!!
如果稍微修改一下程序为:
#include<stdio.h> int main(){ char a,ch; int count=0; while((ch=getchar())!='\n'){ count++; printf("**************\n"); printf("%d\n",count); } return 0; }
可以看到程序只运行了一次就停止了,因为
回车是留在缓存流中的,默认输入了。
小结:
接收
空格,不接收
回车。
3、实例
总结一下两个函数的使用:
输入完成后:
scanf
把数据一把全梭了;getchar
把数据一个一个从兜里掏。
在很多时候会出现这样一种情况,即先输入了一个
scanf的语句,然后可能要用到
gets,这个时候上一个
scanf留下的
回车就会打搅乱下面的数据读取!!!这个时候就需要加一个
回车符(\n),用
scanf('\n);;或者读取这个
回车符(\n),用
gets();或
getchar();。
比如最近在做PTA上的C语言题库时发现的一个题:
给定
n本书的名称和定价,本题要求编写程序,查找并输出其中定价最高和最低的书的名称和定价。
#include<stdio.h> struct book{ char name[31]; double price; }; int main(){ struct book a[10]; int i; double max=-1,min=10000; int flag1=0,flag2=0; int n; scanf("%d",&n); for(i=0;i<n;++i){ scanf("\n"); // 去除回车 //gets(); //getchar(); gets(a[i].name); scanf("%lf",&a[i].price); if(max<a[i].price){ max=a[i].price; flag1=i; } if(min>a[i].price){ min=a[i].price; flag2=i; } } printf("%.2lf, %s\n",a[flag1].price,a[flag1].name); printf("%.2lf, %s\n",a[flag2].price,a[flag2].name); return 0; }
首先使用
scanf输入的书的数量3,留下了一个
回车,如果在这里直接接着使用一个
scanf的话,就会出错:
因为
回车会留在缓存流中,并被下一个函数
get读取到,从而扰乱了本来的数据读取,继而出现了非预期结果。
小结:
一定要注意
scanf的
回车符!!!
二、字符串
1、scanf(%s)
%c和
%s的区别是一个是字符,一个是字符串,从这里可以看得出,
scanf函数能对各种类型进行输入,
而不仅仅局限于字符或是字符串,而字符是
getchar,字符串是
gets。
不过,无论是对待字符还是字符串,
scanf的处理都是比较相似的,这一点倒是比较容易学习和使用,但是 来自
pudn,只有一段开头话:
-
中文版本:在数据大量的情况下,用
gets
读取快于scanf()
10倍以上。 -
英文版本:A large number of cases in the data, using
gets
read faster thanscanf
10 times.
小结:
不接收
空格和
回车
2、gets
到这里,你应该不会忘记上面说过的
scanf是如何处理
回车符(\n)的了,这一点和
gets是差别巨大的!!!
gets对末尾
回车符的处理方式是,接收
回车,但把
回车替换为
\0,不像
scanf是留在缓存中,所以在用
gets时,要注意数组的大小增加1,不然就会出现数组越界等问题。
还是看个例子,还是上面那个题,虽然题中说的是不超过30个字符,但是因为还有一个
回车符转换成的
空字符,所以数组大小需要加1!!!
除了
回车就是
空格的问题了,
gets是接收
空格的,也就是可以读取并输出
空格。
终止的标志是
Enter结束输入(空格不结束),比如这里的
Hello和
World之间的空格就是正常的。
#include<stdio.h> #include<string.h> int main(){ char a[100]; gets(a); int i; for(i=0;i<strlen(a);i++){ printf("%c",a[i]); } return 0; }
如果换成
scanf的话,就只能读取一半了,因为空格也是它的终止符!
#include<stdio.h> #include<string.h> int main(){ char a[100]; int i; scanf("%s",&a); for(i=0;i<strlen(a);i++){ printf("%c",a[i]); } return 0; }
小结:
接收
空格和
回车
3、实例
最直接的方式进行对比就是求一下字符串的长度。
#include<stdio.h> #include<string.h> int main(){ char a[100]; gets(a); printf("%d",strlen(a)); return 0; }
#include<stdio.h> #include<string.h> int main(){ char a[100]; // gets(a); scanf("%s",&a); printf("%d",strlen(a)); return 0; }
这也就解释了为什么前面要用
gets或者是
getchar去去除
回车。
三、总结
scanf
忽略行开头的所有空格,并以各种格式化进行数据输入,直到遇到空格
、回车
结束输入,不接收空格
和回车
,留在缓存区中;getchar
只读取一个字符,包括空格
但是不包括回车
,回车
会留在缓冲区中;gets
读取以任何字符开头的字符串,读取的字符串包括空格
但是不包括回车
,以回车
结束输入,接收空格
和回车
,但之后会丢弃回车
并以\0
代替;
最后的一个图给出常用的
while表达形式:
参考文章
- https://zhidao.baidu.com/question/63301588.html
- https://www.php.cn/faq/415503.html
- https://www.runoob.com/cprogramming/c-tutorial.html
- https://www.cnblogs.com/hlongch/p/5742477.html
- 点赞 4
- 收藏
- 分享
- 文章举报
相关文章推荐
- C语言中getchar,gets,scanf的区别
- C语言中printf,scanf,getchar , puts,gets 的使用及区别
- C语言中gets(),scanf(),getchar()的区别
- scanf()、gets()、getchar()的区别
- 关于scanf与gets的区别和杭州电子科技大学2024程序中出现getchar()
- c语言的输入scanf、getchar、gets解析
- C语言中scanf、gets、fgets的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- scanf() ,getchar(),gets(),fgetc(),fgets(),fscanf()的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- c语言获取用户输入字符串是scanf和gets的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- C语言 gets()和scanf()函数的区别
- c语言获取用户输入字符串是scanf和gets的区别
- C语言 gets()和scanf()函数的区别