引入

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

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

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

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

1
2
3
4
5
6
7
8
9
10
#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个数的程序为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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个数的程序为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#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个数的程序为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#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,炫迈,根本停不来

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