EOF的用法(while(scanf(“%d“,&n) != EOF))和~取反的用法(while(~scanf(“%d“,&n)))

多组输入输出

我们在做题中会有出现以下的情况,
情况一:题中要求在输入数据第一行给出固定数据量比如4,代表接下来需要输入有4行数据。
情况二:没有说固定的数据量,只给出以某一特定标识符作为结束标志,结束输入数据。常见是以输入0作为结束标志。
情况三:与情况二大致一样,但是结束没有固定标识符,以手动结束输入循环。(这种情况我们以EOF(文件结束)作为结束)


输入固定数据量

对于输入固定的多组数据,我们习惯用while() 循环函数解决问题。

常用模板:

#include<stdio.h>
int main()
{
	int T;
	scanf("%d",&T);
	while(T--) //与 T = T - 1 和 T -= 1 等同
	{
	}
	return 0;
}

例题:
题目描述:
计算a+b

输入描述:
输入一个整数T,代表之后有T行数据,每行输入整数a和b

输出描述:
输出a+b的结果

示例1:
输入:

2
1 5
10 20

输出:

6
30

C语言代码

#include<stdio.h>

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		int a,b,sum;
		scanf("%d%d",&a,&b);
		sum = a + b;
		printf("%d\n",sum);
	}
	return 0;
}

运行结果:
在这里插入图片描述



EOF的用法

  • 先给出EOF能来做什么?
    针对多组输入输出且数据没有固定数据量我们通常这样解决问题:采用while(scanf("%d",&n) != EOF)

  • 接下来我们结束EOF的意义:
    EOF对于初学者有些陌生,所以我们先讲原理,EOF全称是End Of File(C语言标准函数库中表示文件结束符),通常在文本的最后表示资料结束。C语言中数据都是以字符的ASCII代码值来存放的。ASCII代码值得范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。
    在这里我们又会问这个跟-1有什么关系,我们可以这样理解把EOF作为‘-1’理解。
    这里就需要我们探本朔源,讲到scanf()的定义了 :
    scanf的语法定义:
    在这里插入图片描述
    scanf(“<格式化字符串>”,<地址表>);
    返回类型为int, scanf()函数返回成功赋值的数据项数,出错时则返回EOF。注意scanf()函数返回int型
    例如scanf(“%d %d”,&a,&b),如果a、b均赋值成功返回值为2,只是a赋值成功返回1,a、b都不成功返回0,出错的时候返回EOF。(EOF不是一个字符,它被定义为是int类型的一个负数-1。)
    所以说,如果我们输入了一个值那么返回就为1,
    即 1 != -1 ,
    即 1 != EOF ,
    即 scanf(“%d”,&n) != EOF
    即 while(scanf(“%d”,&n) != EOF) 中while(A)语句中的事件A是正确即1,while(1){ },进行下一循环。

我们来看框架:
#include<stdio.h>
int main()
{
    int n;
    while(scanf(“%d”,&n) != EOF)
    {
    }
    return 0;
}

  • 我们讲了怎么多组输入数据,接下来就是怎么结束输入了。我们重看之前开篇写的后两种情况,
    情况二:没有说固定的数据量,只给出以某一特定标识符作为结束标志,结束输入数据。常见是以输入0作为结束标志。
    情况三:与情况二大致一样,但是结束没有固定标识符,以手动结束输入循环。

  • 我们分析情况二,以某一特定结束符作为终止循环的条件,通常是将0作为终止标志。
    解决方法:while( scanf("%d",&n) != EOF, n ){ } 我们来看括号中的n代表的是若我们在前一句输入的是0,即此时n = 0即表达式为否需要结束循环,即实现了结束多次输入数据。
    若是将-1作为终止标志,那我们就可以这样写while( scanf("%d",&n) != EOF, n != -1) { } 即当输入-1时,n此时==-1,则表达式n != -1为 -1,结束循环。

  • 分析情况三,无固定结束标识符,手动结束多组输入。
    解决方法:在终端(黑框)中手动输入时,系统并不知道什么时候到达了所谓的“文件末尾”,因此需要用<Ctrl + z>组合键然后按 Enter 键的方式来告诉系统已经到了EOF,这样系统才会结束while.
    比如这样:
    在这里插入图片描述

例题1:
在这里插入图片描述
示例1:
输入:

1 5
10 20
0 0

输出:

6
30

C语言代码:

#include<stdio.h>

int main()
{
	int a,b,sum;
	while(scanf("%d%d",&a,&b) != EOF,a || b)//a || b 代表两者都为0结束,a && b 代表任意一个是0就结束 
	{
		sum = a + b;
		printf("%d\n",sum);
	}
	return 0;
}

运行结果:
在这里插入图片描述

例题2:
在这里插入图片描述
示例1:
输入:

1 5
10 20

输出:

6
30

C语言代码

#include<stdio.h>

int main()
{
	int a,b,sum;
	while(scanf("%d%d",&a,&b) != EOF)
	{
		sum = a + b;
		printf("%d\n",sum);
	}
	return 0;
}

运行结果:
在这里插入图片描述



~取反的用法

~是按位取反的意思。

scanf的返回值是输入值的个数

如果没有输入值就是返回-1,将-1按位取反结果是0

while(~scanf(“%d”, &n))就是当没有输入的时候退出循环,这也符合上面的结束循环条件。

真是不理解拿来就用!背会就行~~~ 😉

我们用~scanf(“%d”,&n)演示一道题:

在这里插入图片描述
示例1:
输入:

4 1 2 3 4 
5 1 2 3 4 5
0

输出:

10
15

C语言代码

#include<stdio.h>

int main()
{
	int n;
	while(~scanf("%d",&n),n)  //while(~scanf("%d",&n) != EOF, n)
	{
		int a, sum = 0;
		for(int i = 1; i <= n; i ++) //循环n次
		{
			scanf("%d",&a);
			sum += a; //sum = sum + a;
		}
		printf("%d\n",sum);
	}
	return 0;
}

在这里插入图片描述


另一种写法,只针对特定标识符结束

我们可以直接写while(scanf("%d",&n) ,n),这个写法不能手动结束,即不能用ctrl+z结束输入。只能通过输入特定数据结束循环。




扩展

没有数据总数,以EOF结束
可能用的几个函数:


  getchar():读入一个字符
  whlie((ch=getchar())!=EOF){
     
  }
  
  gets():读入一行
  while(gets(buf)!=NULL) {
 
  }

用getchar,gets注意读入换行符.

  • 107
    点赞
  • 308
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
### 回答1: 可以使用以下代码实现: ```python #include <stdio.h> int main() { int count = ; // 计数器,记录输入的整数个数 double sum = ; // 求和变量,记录输入的整数之和 int num; // 输入的整数变量 while (scanf("%d", &num) != EOF) { // 循环读入整数,直到输入结束标记 count++; // 计数器加1 sum += num; // 求和变量累加 } if (count > ) { // 如果输入了至少一个整数 double average = sum / count; // 计算平均值 printf("%.2f\n", average); // 输出平均值,保留两位小数 } return ; } ``` 这段代码中,使用了一个while循环来读入若干个整数,直到输入结束标记eof。在循环中,每读入一个整数,就将计数器加1,并将该整数累加到求和变量中。最后,如果输入了至少一个整数,就计算平均值并输出,保留两位小数。 ### 回答2: 这道题目需要我们读取若干个整数直到输入的结束标记eof,然后计算这些整数的平均值并输出,保留两位小数。 我们可以采用循环读取每个整数,并累加求和,同时记录输入数据的个数,最后用求和除以个数即可得到平均值。当输入到eof时跳出循环,并判断是否有数据输入,避免除以0的错误。 以下是具体实现的代码: ```c++ #include <iostream> #include <cstdio> using namespace std; int main() { int n = 0; // 记录输入的整数个数 double sum = 0, num; // sum为输入整数的和,num为当前读入的整数 while (cin >> num) { // 输入不为空时循环 sum += num; n++; } if (n > 0) { // 判断是否有输入数据 double avg = sum / n; // 计算平均值 printf("%.2lf", avg); // 输出结果,保留两位小数 } return 0; } ``` 需要注意的是,本题没有给出整数的范围,因此需要根据实际情况决定采用何种数据类型,这里我们选择了双精度实型double。另外,输入结束标记eof不同编译环境可能有不同的表示方式,例如在Windows系统下可以按Ctrl+Z表示输入结束,在Linux或MacOS下可以按Ctrl+D。 ### 回答3: 题目要求我们输入一些整数,直到读取到eof结束标记。我们需要计算这些数据的平均值,并将结果保留两位小数。在此过程中,我们需要使用double类型来处理实数数据。 首先,我们需要定义一个变量来存储输入的整数数量和总和。我们也需要定义一个变量来存储每个输入的值。我们可以使用循环结构来持续读取输入,直到读取到eof结束标记。 在每一次循环中,我们将读取的值加入总和变量中,并将输入的整数数量加1。最终,我们可以根据它们的数量来计算平均值。我们可以使用以下代码: ``` #include <stdio.h> int main() { int count = 0; double sum = 0; int num; while(scanf("%d", &num) != EOF) { count++; sum += num; } printf("平均值为:%.2lf", sum/count); return 0; } ``` 上述代码中,我们使用scanf来读取整数输入,直到遇到EOF结束标记。在每个循环中,我们将读取的值加到总和变量中,并将计数器加1。 在循环结束后,我们计算平均值。注意要使用double类型来存储数字,以保留小数位。printf函数可以使用%.2lf格式说明符来输出结果保留两位小数。 总体来说,这个问题涉及到的主要是输入输出、循环和变量类型。我们使用循环来读取输入,变量来存储读取到的值、数量和总和,并使用printf函数对平均值输出进行格式化。
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值