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);
复制代码
posted @ 2019-05-22 13:10  unique_ptr  阅读(1825)  评论(0编辑  收藏  举报