scanf函数详解
1.scanf介绍
- scanf是一种格式化函数,意思就是说用户能够按照指定的格式将数据输入到指定的变量中
- 在cplusplus中,scanf函数是这样解释的:
翻译过来就是指:
从stdin这个标准库中读取数据,并根据参数格式它们存储到附加参数所指向的位置,附加参数应该指向已经分配好的对象,这些对象的类型由格式字符串中对应的格式说明符指定
2.%s读取空格问题
scanf函数在使用%s进行读取字符串时,碰到空格会自动暂停读取,例如:
此时scanf只读取了hello,并没有将空格后边的world进行读取,解决方法如下:
int main()
{
char arr[20];
scanf("%[^\n]", arr);
printf("%s\n", arr);
return 0;
}
这里的%【】为格式控制符,具体作用如下:
链接: link
3.缓冲区信息残留问题
当写出这样的代码时,当我们输入1和enter时,我们会发现程序跑出了这样的一个结果:
我们会发现c的值已经不能够被输入了,这是因为在输入a的值时,缓冲区中:
缓冲区中存放了1和\n两个值,其中1被a读取了,而\n被c读取了,解决办法如下:
3.1清理缓冲区
3.1.1缓冲区的作用
既然使用缓冲区会带来这样的问题,那么使用缓冲区的作用是什么呢?
- 解除两者的制约关系
数据可以直接送往缓冲区,高速设备不必等待低速设备,提高了计算机的效率,例如:
打印机在进行打印时,由于打印的速度较慢,需要打印的文字可以存储在缓冲区,打印机再进行逐步打印,这时我们的CPU就可以处理别的事情 - 减少读写的次数
如果每次需要使用数据时传入一次数据,写完数据之后就将数据进行写入,那么这样会浪费很多时间,为此,缓冲区出现了,每次开始读写时将数据先存放在缓冲区,等待缓冲区满了之后再将缓冲区中的数据进行传送,这样会节省很多时间,例如:
我们想将数据写入磁盘中,并不是立即写入磁盘中,而是先将数据保存在缓冲区中,等缓冲区满了之后在将数据写入磁盘中,这样就减少了磁盘的读写次数,增加了磁盘的寿命
资源来源于:链接: link
3.1.2清理缓冲区的方法
资源来源于:链接: link
①使用fflush(stdin)
-
优点
使用起来方便快捷,只需要将这句话放在程序输入语句的前面即可 -
缺点
在c语言中并没有明确规定这种用法,有些编译器中并不支持这种用法,但是如果编译器不支持的话,写出这句话并不会报错,只是缓冲区不会清理罢了
②getchar的连续读取
while (t = getchar() != '\n' && t != EOF)
{
continue;
}
-
优点
通用性好,对所有的编译器都支持 -
缺点
——如果缓冲区中有换行符,但换行符并不是最后一个字符,那么使用getchar会导致换行符前边的所有数据被清理掉
——如果缓冲区中没有换行符,那么while会进入死循环,程序会无故停顿,直到用户按下回车键,影响用户体验
③sebuf
- 原理:使stdin流由默认缓冲区变为无缓冲区
- 优点:
方便快捷,用法如下:
- 缺点:
通用性不好,只适用于widows的大部分编译器,linux和windows的少量编译器在使用时没有反应
④scanf(%*[^\n]%*c)
%[^\n]表示将读取\n前边的所有字符,%后边的表示将之前读取的所有字符丢弃,直到遇到\n操作符停止操作,所以%*c用来清理\n,用法如下:
-
优点:
通用性好,所有编译器都支持 -
缺点
和getchar一样,此方法清理缓冲区根据输入的\n进行是否停止的判断,而且在缓冲区中不存在值时,无法清理缓冲区,例如:
此时缓冲区没有正常清理,我们进行这样的转换:
可以发现,此时缓冲区被清理了,而如果我们只需要清理\n时,可以改写成: