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注意读入换行符.
更多推荐
所有评论(0)