输入流,scanf,getchar,fflush,fgets与gets详解

目录

前言

一、什么是输入流?

二、输入函数(部分)

2.1scanf函数

2.1.1基本格式: %[*][宽度][长度]说明符           

2.1.2除了[*]修饰符外的修饰符及作用:

2.1.3格式符说明:

2.1.4附加格式说明字符表·修饰符说明

2.2scanf使用时的注意事项:

2.2.1scanf函数中断问题

2.2.2scanf函数输入了超过其变量承受范围的数据(缓冲区问题):

2.2.3新手上路时易犯错误:

 2.3getchar()使用的注意事项:

2.3.1getchar的括号内部不可以有参数

2.3.2getchar()在读取错误时会返回字符EOF也就是整形数值-1。

2.4fgets与gets

2. 5fflush的现状:

2.5.1 fflush(stdin)在高版本中已经不再使用(经测试,VC6.0完美支持,vs2015及以后版本不再支持,GCC(GCC4.6.2)不支持)

2.5.2尽管现在fflush(stdin)使用较少,但是fflush(stdout)在查看错误指示器的时候的效果仍然出众。


前言

本文章主要着眼于输入流,主要有以下几个方面:

    1.scanf函数的一些特殊用法及常规用法

    2.scanf函数使用时需要注意的事项

    3.getchar一些使用规则

    4.fgets与gets的关系及一些编译器报错的问题

    5.fflush在输入,输出流中的应用


一、什么是输入流?

输入流:用白话讲就是把数据从某处读出来。

比如:我们可以从键盘上获取数据(标准输入流),也可以从已有文件中获取数据,等等。

那么我们将在第二部分介绍一些输入函数。

二、输入函数(部分)

2.1scanf函数

2.1.1基本格式: %[*][宽度][长度]说明符           

对于每一部分的理解可以参照printf函数:

比如:printf(“%*d %d”,a,a,b)的意思是跳过读取到的第一个整数,将读取到的第二,三个整数以一列宽,整形长度打印出来。

      但如果去掉 “  *  ”

2.1.2除了[*]修饰符外的修饰符及作用:

 修饰符介绍           作用介绍

%[a-z]

读取在 a-z 之间的字符串,如果不在此之间则停止(仅为例子,并非唯一)

%[^a-z]

读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止(仅为例子,并非唯一)

%*[^=]

前面带 * 号表示不保存变量。跳过“  =  ”前的字符串(此仅是举个例子也可以不是“=”,而是其他符号),跳过字符后还应把值保存下来,可以参照下方例子

%[^=] 

读取字符串直到碰到’=’号,(’^’后面可以带更多字符不必是“=”)

总结%[ ] 类型

%[ ]表示要读入一个字符集合, 如果[ 后面第一个字符是”^”,则表示反意思。“*”表示跳过读取的意思。

 [ ]内的字符串可以是1或更多字符组成。空字符集(%[])是违反规定的,可导致不可预知的结果。%[^]也是违反规定的。

即 "%" , "[]" , "^" , "*" 不是变数,其他均可按照要求来自行规划。 


(2)的代码及结果 
 

2.1.3格式符说明:

格式符说明

%c 

 读入一个字符

%d

读入十进制整数

%i

读入十进制,八进制,十六进制整数

%o

读入八进制整数

%x,%X

读入十六进制整数

%s

读入一个字符串,遇空格、制表符或换行符结束

%f,%F,%e,%E,%g,%G

用来输入实数,可以用小数形式或指数形式输入

%p

读入一个指针

%u

读入一个无符号十进制整数

%n

至此已读入值的等价字符数

%[]

扫描字符集合

%%

读%符号

%a,%A

读入一个浮点值(仅C99有效)
...................................................................................................................

2.1.4附加格式说明字符表·修饰符说明

长度修饰符:(用于指定整型变量的长度)

注意:黄色行表示 C99 引入的说明符和子说明符。

  • 宽度:用数字表示读取或输出的最大字符数。例如,"%5d"表示读取或输出最多5个字符的整数。
  • 精度:对于浮点数,用".数字"表示小数点后的位数。例如,"%.2f"表示只保留两位小数的浮点数。

另附:scanf是没有输入精度一说的。

2.2scanf使用时的注意事项:

2.2.1scanf函数中断问题

scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束,是数据的输入被截断效果与%[字符])。

  ① 遇空格、“回车”、“跳格”键。

  ② 遇宽度结束。

  ③ 遇非法输入。(自发的键盘输入)ctrl+z(终止scanf函数继续读取数据),也有其他情况

 

2.2.2scanf函数输入了超过其变量承受范围的数据(缓冲区问题):

scanf()的特殊之处在于,它会将原本用于分隔输入的空格和转义字符转入变量,

此种情况即为,把空格转入了变量b中。

 那么如何消除缓冲区中的无用数据呢?

我们可以使用getchar()来吸收少量的多余字符,也可以用scanf()函数来吸收

 但当多余字符较多时,我们可以使用getchar(),scanf()循环来清理缓冲区,也可以使用

上文提过的scanf(%[^\n]s)的形式搭配getchar()来清除。也可以使用fflush(stdin)在vs2015版本及其以后似乎这个方法可以使用,但没有效果,可以使用rewind(stdin)进行代替

2.2.3新手上路时易犯错误:

1.没对变量取地址,

2.格式符与输入变量类型不符(比如char c;scanf(“%s”,&c);),

3.头文件未引用导致报错,

4.搞不清楚scanf给数组赋值时什么时候需要取地址什么时候不需要取地址(观察你用scanf复赋值的对象,若其为指针类型,则无需取地址,反之则需要,对于数组而言取地址与否没有影响,因为数组名(既没有取地址的时候),与取地址数组名有相同的地址)

 2.3getchar()使用的注意事项:

2.3.1getchar的括号内部不可以有参数

2.3.2getchar()在读取错误时会返回字符EOF也就是整形数值-1。

关于为什么getchar的返回值时int而不是char:其实可以从某方面证明char也是一种int类型的数据

2.4fgets与gets

在支持C99的某些编译器上gets函数是不能使用的,而fgets是可以使用的

fgets的参数及用法与gets的参数及用法及某些情况下的替代

fgets的用法:

以下是cplusplus对fgets参数的解释:

关于gets函数参数的定义及说明:

请注意,gets 与 fgets 完全不同:gets不仅使用 stdin 作为源,而且在生成的字符串中不包含结束换行符,并且不允许指定 str 的最大大小(这可能导致缓冲区溢出)。

fgets在获取字符串的时候与scanf(%[^\n]s)有异曲同工之妙,故scanf可以作为fgets和gets的一个替代。 

2. 5fflush的现状:

fflush主要用于输入输出流缓冲区的清空:

2.5.1 fflush(stdin)在高版本中已经不再使用(经测试,VC6.0完美支持,vs2015及以后版本不再支持,GCC(GCC4.6.2)不支持)

在vs中fflush(stdin)已经被替代为rewind(stdin)。

2.5.2尽管现在fflush(stdin)使用较少,但是fflush(stdout)在查看错误指示器的时候的效果仍然出众。

  • 20
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木鱼不是木鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值