玩转N组输入和多组输入


title: 玩转N组输入和多组输入
date: 2023-10-18 22:39:57
tags: C语言 多组输入
cover: https://picbed0521.oss-cn-shanghai.aliyuncs.com/blogpic/Snipaste_2023-10-20_07-34-35.jpg

原文见我的网站: www.supdriver.top

引入

当我们在写IO型OJ时,多组输入便是我们绕过不开的话题了,但不用担心,可能初见多组输入会觉得难以理解,但用多了之后就会发现,多组输入 花样并不多,混熟了就很简单了

先看看一组输入输出如何完成的

如图:一组输入时,用scanf获取一组输入,并在主体部分完成数据的处理,产生结果,最后用printf输出产生的一组结果。

以下用实现加法的程序做演示

#include <stdio.h>

int main()
{
    int a,b;
    scanf("%d %d",&a,&b);//获取一组输入
    int sum = a + b;//产生结果
    printf("%d\n",sum);//输出结果
    return 0;
}

然后升级到N组输入

有的OJ题在一个测试文件中会先输入一个n,告诉你接下来有n组输入,你就要产生n组输出,也就是说要将一组输入输出重复性地完成n次。难道我们要把代码重复n次吗?显然不现实。

所以是时候使用循环了,具体用法如下

如图,先用一个scanf获取循环次数n,然后创建一个循环,将一组输入输出放入循环体,一次一次循环处理即可

变量的重置

为防止前后两次循环产生干扰,有两种处理变量的方式

1.(推荐)除了输入的变量,其它所有变量在循环体内声明,这些变量会在一次循环后销毁,下一次循环开始时自动重新声明,从而完成变量的自动重置

以下面这个一次求和3个数的程序为例

#include <stdio.h>

int main()
{
    int n = 0;
    scanf("%d",&n);//获取循环次数n
    for(int i =0;i<n;i++)//创建循环
    {
        //以下完成一组输入输出
        int sum = 0;//声明一个局部变量,下次循环时会自动重声明
        int num = 0;//储存输入的数字
        for(int j =0;j<3;j++)
        {
            scanf("%d",&num);
            sum+=num;
        }
        printf("%d\n",sum);//完成输出
        //本次循环走完后变量sum被销毁,然后进入下一次循环,完成重置
    }
    return 0;
}

2.在循环外部声明变量,然后在循环末尾手动重置变量

以下面这个一次求和3个数的程序为例

#include <stdio.h>

int main()
{
    int sum = 0;//声明在循环外部
    int n = 0;
    scanf("%d",&n);//获取循环次数n
    for(int i =0;i<n;i++)//创建循环
    {
        //以下完成一组输入输出
        int num = 0;//储存输入的数字
        for(int j =0;j<3;j++)
        {
            scanf("%d",&num);
            sum+=num;
        }
        printf("%d\n",sum);//完成输出
        sum = 0;//重置sum
    }
    return 0;
}

要不要用数组储存输入,或储存结果再一次性输出?

答案是:可以,但没必要

只需要像上图那么写即可,因为输入是一次性喂进去的 。存数组再输出,和每产生一个结果就输出一次,最终呈现出来是一样的(如下图)

现在,勇士,来挑战多组输入吧

scanf的返回值

多组输入时,究竟会输入多少组数据,也不告诉你了,但是,此时scanf的返回值就派上用场了。和我们在终端手打输入不同,OJ的输入是喂一个文件进去,所以当输入结束时scanf的返回值是EOF(意为文件结尾end of file),而当成功输入数据时,则会返回输入数据的个数(文档截图如下)

结合循环

那么就把scanf放入while循环吧,每次试图获取下一组输入时,检测是否返回值为EOF,若是,则跳出循环,结束程序;若否,则继续循环

以下面这个一次求和3个数的程序为例

#include <stdio.h>
int main()
{
    int num = 0;//先声明至少一个待输入的变量
    while(scanf("%d",&n) != EOF)//创建循环,每次循环开始时scanf一次,并检测是否返回EOF
    {
        //开始构建循坏体
        int sum = 0;
        sum+=n;
        //完成剩下的两次输入
        for(int i =0; i < 3 - 1;i++)
        {
            scanf("%d",&n);
            sum+=n
        }
        printf("%d\n",sum);//完成一次输出
    }
    //scanf返回EOF后跳出循环
    return 0;
}

基本架构

以后再要写多组输入,基本就像上面那个程序一样

1.先声明至少一个待输入的变量

2.创建循环,每次循环开始时scanf一次,并检测是否返回EOF

3.开始构建循坏体(包括完成剩下的输入,完成一组输出)别忘了回车!!!

4.直至scanf返回EOF后跳出循环

想模拟一下多组输入看看?

像下图一样每组数据间加个空格就行,什么?题目的样例输入有回车?不用管它,放心大胆地换成空格就行。自己测试程序,只需要输出一样就行,至于怎么输入,没必要和题目一模一样

注意!!!不要试图在终端停止程序

因为和OJ不同,在本地运行程序时,不是文件输入,而是终端输入,没法让scanf返回EOF,炫迈,根本停不来

*一样就行,至于怎么输入,没必要和题目一模一样

[外链图片转存中…(img-IhjFdshi-1747377476712)]

注意!!!不要试图在终端停止程序

因为和OJ不同,在本地运行程序时,不是文件输入,而是终端输入,没法让scanf返回EOF,炫迈,根本停不来

你要是想立即中断程序,那就按ctrl+c

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值