ACM中常用的输入输出方式
不论是在ACM/ICPC这样类型的比赛中,还是在做项目中,对于输入输出的格式尤为重要,不可以想当然的按自己那一套走,我们需要根据题目要求进行操作,对于第一次接触这方面比赛的小白,最为常见的现象便是类似于下面这行代码
1 printf(“请输入一组数据:”); 2 cout<<"输出的结果为";
倘若题目没有要求你,千万不要有多余的输出,虽然在测试的时候方便自己,但也麻烦在提交运行时注释掉,因为电脑可没有你的大脑那样灵活,他要对比的数据很死板,多一个空格少一个空格都不行,所以,在这一块的处理一定要细心!细心!再细心! 下面我们来看下常见的输入输出格式有哪些
一、基本输入输出
1、单组输入输出
已知题目有两个变量a和b,现在就要输入a和b,操作如下
1 //C 2 scanf("%d %d",&a,&b); printf("%d %d\n",a,b); 3 //C++ 4 cin>>a>>b; cout<<a<<b<<endl;
这个很简单,那么如果题目输入n组a和b怎么办呢
2、n组输入输出
1 //C 2 scanf("%d",&n); 3 while(n--) {scanf("%d %d",&a,&b); printf("%d %d\n",a,b);}
4 //C++
5 cin>>n;
6 while(n--){cin>>a>>b;cout<<a<<b<<endl;}
也没有那么难嘛,现在如果n不告诉你,要求输入多组a和b该如何操作呢?
3、多组输入输出(重点来了!!!)
1 //C 2 while(scanf("%d %d",&a,&b)!=EOF){printf("%d %d\n",a,b);}//第一种写法 3 while(scanf("%d %d",&a,&b)==2){printf("%d %d\n",a,b);}//第二种写法 4 while(~scanf("%d %d",&a,&b)){printf("%d %d\n",a,b);}//第三种写法 5 //C++ 6 while(cin>>a>>b){cout<<a<<b<<"\n";}
竞赛中经常采用这种输入输出方式。我们来看看上面第二点,输入n组a和b如何也像这样的格式进行操作
1 //C 2 while(scanf("%d",&n)!=EOF)//第一种写法 3 { 4 while(n--) 5 { 6 scanf("%d %d",&a,&b); 7 printf("%d %d\n",a,b); 8 } 9 } 10 while(scanf("%d",&n)==1)//第二种写法 11 { 12 while(n--) 13 { 14 scanf("%d %d",&a,&b); 15 printf("%d %d\n",a,b); 16 } 17 } 18 while(~scanf("%d",&n))//第三种写法 19 { 20 while(n--) 21 { 22 scanf("%d %d",&a,&b); 23 printf("%d %d\n",a,b); 24 } 25 } 26 //C++ 27 while(cin>>n) 28 { 29 while(n--) 30 { 31 cin>>a>>b; 32 cout<<a<<b<<"\n"; 33 } 34 }
【敲重点了】有没有发现,对于多组输入的a和b,是边输入边输出,而不是将这些数存到某数组里面,在输入结束时,再对其进行分别输出。如果你还是小白,千万不要忽视这一点,兴许你现在还没不以为然,但一定要有这个思维。请记住,如果输入的每组数据的结果不相互干扰的话,就可以在本次操作的时候将该组数据的相关结果进行输出。
二、复杂的输入输出
1、读入多行,且每行数据个数不确定
是不是已经对输入输出有一点感觉了,那么来考验下你的C语言基础。
已知题目,每一行有多个数据(不知道有多少个数),每个数据之间以空格相隔。碰到这种情况怎么做呢,学过C语言都知道一行一行读入有getline(),也可以一个一个字符读入的getchar(),而C++中有流的操作,具体操作有以下几种办法
1 //getchar()版本 2 int fg=0;//用于判断a中是否存放了数字 3 int a=0;//每个数据读入a中 4 char c=getchar();//一个一个的读入 5 while(c!='\n') 6 { 7 if(fg==1&&c==' '){printf("%d ",a);a=0;fg=0;continue;}//跳过空格 8 fg=1;//表示fg中已经存放了数字 9 a=10*a+c-'0';//将字符转为整型变量 10 } 11 12 //getline()版本 13 int fg=0;//用于判断a中是否存放了数字 14 int a=0;//每个数据读入a中 15 string ss; 16 while(getline(cin,ss)) 17 { 18 int cn=0; 19 while(s[cn]!='\n') 20 { 21 if(fg==1&&s[cn]==' '){printf("%d",a);a=0;fg=0;}//跳过空格 22 else if(ss[cn)!=' '){ 23 fg=1;//表示fg中已经存放了数字 24 a=10*a+c-'0';//将字符转为整型变量 25 } 26 cn++; 27 } 28 } 29 30 //利用流的操作版本 31 string ss,st; 32 while(getline(cin,str)) { 33 stringstream ss(str); 34 while(ss>>st) printf("%s",st.c_str()); 35 }
是不是有点烧脑了,如果要处理稍微复杂的输入,则至少需要掌握这方面的一种方法,尤其在碰到整行读入时可以利用getline(),将每行读入到字符串中,再对字符串进行相关操作,当然方法不止以上三种,像cin.getline()等都可以进行相关操作
2、文件流的操作
(1)重定向(必须掌握)
1 freopen("1.txt","r",stdin);
掌握了它,在本地测试时可以提前将数据存放在同目录下的 1.txt(文件名要于freopen()中的文件名一致) 文件中,然后在本地运行时,它将自动读入数据。记得今年蓝桥杯省赛时,有一组数据非常多(有的题目的数据无法拷贝),如果不知道重定向,那么每次本地运行测试时,都要手动输入,将会浪费很多时间。
(2)文件流的操作(有的题目会有这方面要求)
1 //C++语法 2 ifstream fin("in.txt"); 3 ofstream fout("out.txt"); 4 int a,b; 5 while(fin>>a>>b) fout<<a+b<<endl; 6 fin.close(); 7 fout.close(); 8 9 //C语法 10 FILE *fin,*fout; 11 int a,b; 12 fin=fopen("in.txt","r"); 13 fout=fopen("out.txt","w"); 14 while(fscanf(fin,"%d %d",&a, &b) != EOF) 15 fprintf(fout,"%d\n",a+b); 16 fclose(fin); 17 fclose(fout);
三、总结输出格式
1、每个数据间以空格相隔,行末不得有多余的空格
//C++ if(first) first=0;//first判断是否时每行第一个元素 else cout<<“ ”; cout<<a; //C语法 if(first) first=0; else printf(" "); printf("%d",a);