非常绕的“输入结束”信号

文章讲述了如何在编程中处理不定数量的整数输入,难点在于接收用户的“输入结束”信号。通过实例和Windows/Linux下的Ctrl+Z与Enter组合,展示了如何利用scanf的返回值和EOF来实现正确接收并计算整数的最小值、最大值和平均值。
摘要由CSDN通过智能技术生成

【题目描述】

输入一些整数,求出它们的最小值、最大值和平均值(保留3位小数)。输入保证这些数都是不超过1000的整数。

【样例输入】

2 8 3 5 1 7 3 6

【样例输出】

1 8 4.375

【题目来源】

刘汝佳《算法竞赛入门经典  第2版》 例题2-5 数据统计

【解析】

本题的难点在于,输入整数的个数是不确定的。因为不知道会输入多少个整数,程序只能通过循环不断要求用户输入,直到用户发出“输入结束”信号。

循环输入的代码很简单,但是用户的“输入结束”信号是什么呢?程序怎么接收这个信号呢?

按我们以前的经验,都是输入后按Enter键后开始输出,比如求两个整数的和。

#include<stdio.h>
int main(){
    int a,b;
    scanf("%d %d", &a, &b);
    printf("%d\n", a+b);
    return 0;
}

输入两个整数后按Enter,程序就会输出结果,看起来Enter键就是“输入结束”信号。但是假如我们在输入第一个数后就直接按Enter呢,你发现程序并没有输出任何结果,它依然在等着你输入,由此可见Enter并不是“输入结束”信号。

Enter发出的是“提交”信号。输入一个数,按Enter相当于对scanf说:老哥,给你交1个数!

但scanf要的是两个数,回答:老弟,你只交了1个,还差1个,继续!

所以,当你欠scanf老哥数字债时,不管按多少个Enter都无法结束输入。

如果输入9 5 2 7后按Enter,就是对scanf说:老哥,给你交4个数。

scanf老哥一看要求满足了,也不贪心,只取前两个,后面赠送的忽略不计。

那用什么发出“输入结束”信号,之前的文章“用恋爱脑搞懂scanf的返回值”已有介绍,在Windows下,输入完毕后按Enter键,然后按Ctrl+Z键,再按Enter键,即可结束输入。在Linux下,输入完毕后按Ctrl+D键即可结束输入。

显然,Windows下“Ctrl+Z”就是“输入结束”信号,为什么输入这个信号后还要加上一个Enter呢?别忘了,Enter的作用是“提交”,它得把这个“输入结束”信号“提交”给程序。

注意使用这个“输入结束”信号有两个条件:

①“输入结束”信号只是对当前的scanf老哥发出的,并不是对整个程序发出,因而它只能结束当前的scanf输入。

②“输入结束”信号要正常发挥作用,必须是在当前scanf语句未输入任何数据前按Ctrl+Z。

换句话说,上面的代码要想使用Ctrl+Z结束输入,只能在程序运行后,在未输入任何数据时就先按Ctrl+Z,然后程序就会在没有输入任何数据的情况下结束输入。

所以,准确地说,Ctrl+Z发出的“输入结束”信号是没有任何输入的“输入结束”信号。

这么看这个Ctrl+Z根本没个鸟用。

事实并非如此,因为当Ctrl+Z在发出“输入结束”信号的同时,scanf()函数会返回EOF(实际值为-1),咱们可以利用这个返回值再借助于循环实现有数据输入的“输入结束”。

代码如下:

#include<stdio.h>
#define INF 1000000000
int main(){
    int x, n = 0, min = INF, max = -INF, s = 0;
    while(scanf("%d", &x) == 1){
        s += x;
        if(x < min) min = x;
        if(x > max) max = x;
        n++;
    }
    printf("%d %d %.3f\n", min, max, (double)s/n);
    return 0;
}

当输入完数据后,按Enter键再按下Ctrl+Z,然后再按下Enter,就会向当前正在执行scanf函数发出“输入结束”信号,当前scanf函数在没有任何有效输入的情况下结束输入。此时scanf返回EOF,致使循环条件不成立,结束循环。

为什么输入数据后要先按下Enter键再按Ctrl+Z呢?因为这样才能满足上面说的第②个条件。

不过上述代码不先按Enter键也是能正常运行的,甚至在输入完数据后按任何一个字母都能输出正确结果。这是因为当输入的不是整数时,匹配失败,scanf函数会返回0,同样能结束循环。注意:此时Ctrl+Z只被当作字符串处理,而不会被scanf视为“输入结束”信号。

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

金创想

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

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

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

打赏作者

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

抵扣说明:

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

余额充值