scanf的特殊运用

在多数情况下,scanf()工作得很好。但在一些特殊的场合,却会造成-些困扰。(1)当输入double类型的数据时,如果有声明double d,那么使用scanff("%f", &d);
将得不到想要的结果。正确的输人格式是使用%lf。scanf(“xlf”, &d);
(2)当输人的char类型数据不是第一 项时,
如果char数据的输入是在其他数据之后,那么就必须小心使用scanf()。例如int i char C;
scanf("%d%c", &i, &c); //注意两个格式占位符间没有分隔符如果有如下形式的键盘输人。123 A.
那么,i会得到正确的输人123,但c的值却不是’A’,而是空格!为什么会有这样的结果呢?这里先要简单解释- 下scanf()的工作原理。与getchar()-样,scanf()也是一-种带缓冲的输人。在用户输人一行信息并按回车后,输人的信息会以字符串的形式先存放到系统缓冲区中,然后scanf()再从这个缓冲区中读取数据。在此例中,scanf() “知道”第一个输人项应该是整数,因此它尝试依次从缓冲区中读取数字字符。一且遇到第一一个不属于数字的字符,那么该次读:取结束,以前读人的那些字符将按规则转化成整数并存放到指定的变量1中。此后,scanf()按第2个格式(字符格式)读取后续的数据。而此时,缓冲区中的当前字符(也就是终止了上一次读取的字符)是空格,刚好符合格式要求,因此C得到空格也就不奇怪了。此时,字符’A’留在了缓冲区中,没有被读取。
为解决上述问题,可以使用如下方式。
scanf("%d %c”,&i, &c); //两个格式占位符间加人一个空格
在这种情况下,scanf()的格式字符串中有不属于格式占位符的字符(此例中是空格),那么在输人的时候必须在输人项间加入一个空格以匹配要求。而例中的输人刚好符合要求。
另一种解决问题的方法是不改变scanf()的格式字符串,而在输人时将字符数据紧接在整数亏面输人:
123A.
第3种解决方案是用getchar()函数来读取字符数据。
(3)在一条scanf()后用另一条scanf()或getchar()语句读取字符数据时,如果有声明int i;
char C = ‘A’;和语句序列
scanf("%d", &i);
scanf("%C”, &c); //或者c = getchar();
printf("%d,%c", i, c);当用户键入如下输人后,123./
第2条scanf()或getchar()将不会等待用户输人而会立即返回,
123 ,
这又是为什么呢? 明确要求输出空行(即
打印-个"\n’ 字符)。显然,唯一合理的解释就是字符C的值是请注意在输出结果中,当前光标位置前有一一个空行,但程序代码并没有\In’。读者不禁要问:这里才完成第一一次输人,而第二次输人还没有开始呢!即使要打印,那么c的值也应该是’A ,怎么也不会是‘\n’ 啊!
造成以上错误结果的“罪魁祸首”仍然是scanf()的缓冲特性。在此例中,所有用户输人,包括最后输人的回车符都被存入了缓冲区。标志着输入结束的回车符将使scanf()的第一次输人结束。而当第二条带缓冲的输人函数执行时,如果要求输人的碰巧是一个字符,那么残留的回车符正好满足这个需求,因此丽数立即返回,而指定的字符变量将会得到‘\n’。
这是scanf() 函数的一个潜在缺陷。解决问题的方法就是在每一条scanf()后面加上一条getchar()语句以接收残留在缓冲区的‘\n’。 例如:
scanf(“%d", &i); getchar();scanf("%C”" &C);
但这种方案还有一个缺陷。如果输人是123ABC/X并期望i到123而c得到X,那么getchar()办不到将ABC全部吸收掉,C 的值将是‘B’, 而getchar()只能吸收掉’A’。 所以,要想实现预期结果,一个更有效的方法是使用fflush()函数,具体做法如下:
scanf(“%d”, &i); fflush(stdin);scanf("%C”", &c);
其中,ff1ush(stdin)将清除标准输入缓冲区中的所有残留,从而使下次输入结果正确。
关于scanf()更多的情况需要读者在实践中加以总结,这里就不再深人讨论了。
(摘录自课本-c语言程序设计)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值