ACM竞赛的输入输出数据一般都有多组(不定),并且格式多样(数,字符,字符串..)
因此处理多组数据是基本要求
这里除了雨巨介绍的,还整理了其他方法,分类做一下笔记省得我忘记
第一类
不说明有几组输入,以EOF为结束标志
EOF(文件结束符)是c语言预定义的常量,值为-1,表示文件结束
在 Windows系统中 在新的一行的开头 Ctrl+Z 就表示 EOF
第一种
while(scanf(%d %d)!=EOF)
scanf()函数返回值为成功读取数据个数(比如上行成功读取了2个数,返回值为2)当未读取到数据时返回EOF
因此也可以这么写
第二种
while(scanf(%d %d)==2)
第三种
while(cin >> n)
如果输入流正常,就会继续循环获取值,如果输入流错误,或者达到文件末尾(EOF),循环结束
第四种
while(~scanf("%d, &n))
~ 是按位取反,EOF值为-1
100000000000000000000000000000001-原码
11111111111111111111111111111111111110-反码
11111111111111111111111111111111111111-补码
计算机储存的是补码,EOF的补码按位取反后结果为
000000000000000000000000000000000
为假,循环停止,非0为真,循环继续
第二类
输入一开始告诉你有n组数据,后面跟着n组数据
例:
这个好耶 先输入n再写个循环读取n组数据就行了
scanf("%d",&n); //或cin >> n; while(n--) //或for(i=0;i<n;i++) { ... }
第三类
不说明有几组输入,但以某个特殊输入为结束标志
例: 以0 0为结束标志
写成一行容易写错成
while(scanf("%d %d",&a,&b)==2 && (a!=0 && b!=0))//错误代码
读到2个都是0就结束的逆否命题是只要有1个不是0就不结束
因此上行代码中&&应改成||,如下
while(scanf("%d %d",&a,&b)==2 && (a!=0 || b!=0))//正确代码
&&在while()括号里面的应是特殊条件的逆否命题,但得出逆否命题很容易出错
更万无一失的写法是把特殊条件的原命题写在循环内部,如下
while(scanf("%d %d",&a,&b)==2) { if(a==0 && b==0) break; ... }
这样写多了一行,但写原命题不会出错吧(大概)
第四类
以上三类的结合
懒得写了
第五类
输入是整行字符串(或单个字符)
C语法:
char a[20]; gets(a); //雨巨:"gets在c++14以后的标准里面被禁用了,不安全,某些oj会ce."
C++语法:
char a[20]; cin.getline (a,20);
或者使用string类型(头文件记得包含#include <string>
)
string a; getline (cin,a);
PS:
若使用scanf()函数
scanf(%s%s”,str1,str2)
在多个字符串之间用一个或多个空格作分隔
若使用gets()函数
gets(str1); gets(str2);
在多个字符串之间用回车符作分隔
通常接受短字符串用scanf()函数,接受长字符串用gets()函数
getchar()每次只接受一个字符,常用a = getchar();
笔记整理自雨巨,lcy老师等大牛
欢迎大佬补充