# **ACM题目中常用的输入输出方式**
* 由于ACM竞赛题目的输入数据和输出数据一般有多组(不定),并且格式多种多样,所以,如何处理题目的输入输出是对编程者最基本的要求。
* 多组输入的意思是在代码运行完一组数据后,仍能继续运行下一组数据,直到文件内的数据运行完为止。下面会以a+b 为样例来讲解。
## **输入**
### **第一类**
题目中告诉我们需要运行几组数据。如:<br>
输入数据有T组,每组占一行,有两个整数a, b。
你需要计算每组数据之和并输出。
原题:[链接](http://acm.hdu.edu.cn/showproblem.php?pid=1090)
#### 代码
```
C
#include<stdio.h>
int main()
{
int T;
int a,b;
scanf("%d",&T);
while(T--)
{
scanf("%d %d",&a,&b);
printf("%d\n",a+b);
}
return 0;
}
C++
#include <iostream>
using namespace std;
int main(){
int T,a,b;
cin>>T;
while(T--){
cin>>a>>b;
cout<<a+b<<endl;
}
return 0;
}
```
上面代码中while(T--)我们也可以用for循环来写,如for( i=0; i<T; i++)。
### **第二类**
题目中没有说明需要运行多少组数据,而是说要运行到文件结束,或者是要求以EOF为结尾,亦或者以某某数等于0为结尾。如:<br>
输入包含多个测试用例,一个包含一行。 每个案例以整数N开头,然后在同一行中跟随N个整数。
输出对于每一行N个整数之和。
例题:[链接](http://acm.hdu.edu.cn/showproblem.php?pid=1094)(以EOF为结尾)
[链接](http://acm.hdu.edu.cn/showproblem.php?pid=1093)(以a和b都等于0为结尾)
#### 代码
```
C
#include <stdio.h>
int main()
{
int a,i,n,sum;
while(scanf("%d",&n)!=EOF)
/*还可以这样写while(~scanf("%d",&n)),但如果题目要求以EOF为结尾,则必须用EOF*/
{
sum=0; /*sum不能在循环外进行处理*/
for(i=0;i<n;i++)
{
scanf("%d",&a);
sum+=a;
}
printf("%d\n",sum);
}
return 0;
}
C++
#include<iostream>
using namespace std;
int main(){
int a,i,n,sum;
while(cin>>n){
sum=0;
for(i=0;i<n;i++){
cin>>a;
sum+=a;
}
cout<<sum<<endl;
}
return 0;
}
```
以a和b都等于0为结束的代码就写个主要的while循环,while(cin >> a >> b && (a != 0 || b != 0)) 。
#### **字符串输入**
在学习时,我们经常会遇到关于字符串的应用,有的题目中会告诉你该字符串有几个字符组成,这样的输入很简单,我们不再做详解;我们在这里主要讲一下未知字符串的输入,也就是说不知道有几个字符。我们存储字符串时一般用字符数组,现在我们定义一个字符数组:
`char ch[100] ;`
1. **字符串中没有空格**
当字符串中没有空格时,这样的输入就相对简单了,可以直接用 **%s**(以空格或回车为结束符) 去接收,或者用C++的**cin**(同样以空格或回车为结束符) 即可:
`scanf("%s",ch); //(C++) cin>>ch;`
2. **字符串中有空格**
当字符串中有空格时,%s就不适用了,原因上面已讲明。当然,无论字符串中又没有空格都会以回车为结尾,所以我们可以循环接收**字符**并加以判断即可:
```
int x=0;
char a;
while(scanf("%c",&a)!=EOF&&a!='\n')
ch[x++]=a;
```
上面是C语言的写法,相比来说我更喜欢C++的方法,因为简单,只有一个函数**getline**。
`getline()的原型是istream& getline ( istream &is , string &str , char delim );`
其中 **istream &is** 表示一个输入流,譬如cin;**string &str**表示把从输入流读入的字符串存放在这个字符串中(可以自己随便命名,str什么的都可以);**char delim**表示遇到这个字符停止读入,在不设置的情况下系统默认该字符为'\\n',也就是回车换行符(遇到回车停止读入),如:
`getline(cin, ch);`
- 简介
- 零基础快速入门ACM
- C语言快速入门
- C语言快速入门
- C/C++基础
- 输入输出
- 数组和字符串
- 数组
- 字符数组
- 函数和递归
- C++标准容器库(STL)
- Vector
- Map
- Set
- String
- Stack
- Queue
- Priority_queue
- 贪心
- 硬币问题
- 区间调度问题
- 字典序最小问题
- 独木舟问题
- 搜索
- DFS
- BFS
- 剪枝
- 记忆化搜索
- 常用技巧
- 倍增
- 高精度
- 大数加法
- 大数减法
- 大数乘法
- 大数除法
- 大数阶乘
- 输入挂
- 前缀和
- 二分
- 本地预处理
- 尺取
- 枚举
- 坐标离散化
- 分治
- 数列分治
- 树上分治
- 平面分治
- 计算几何
- 凸包
- 点积
- 叉积
- 线段关系
- 皮克定理
- 最近点对
- 数据结构
- 线段树
- 树状数组
- 并查集
- 动态规划
- 基础知识
- 信息学竞赛中的动态规划
- 动态规划初步
- 最长上升子序列(LIS)
- 最长公共子序列(LCS)
- 最大子段和
- 背包问题
- 部分背包
- 0 1 背包
- 完全背包
- 多重背包
- 背包的可行性问题
- 线性DP
- 树形DP
- 区间DP
- 数位DP
- 动态规划优化
- 字符串
- KMP算法
- 拓展KMP
- 字符串Hash
- Manacher算法
- 后缀数组
- Trie树
- 博弈论
- Nim博弈
- Bash博弈
- 斐波那契博弈
- 威佐夫博弈
- SG函数
- 数论
- 整数研究
- 素数判断
- 素数筛选
- 快速幂
- 算数基本定理
- 最大公约数(Gcd)
- 费马小定理
- 扩展欧几里得
- 逆元
- 同余定理
- 组合数学
- 容斥原理
- 抽屉原理
- 卢卡斯(Lucas)
- 卡特兰(Catalan)
- 著名函数
- 欧拉函数
- 莫比乌斯函数
- 线性代数
- 矩阵运算
- 矩阵快速幂
- 图论
- 存图方法
- 邻接矩阵
- 邻接表
- Vector存图
- 链式前向星
- 图的遍历
- 拓扑排序
- 最短路
- Dijkstra算法
- SPFA算法
- Floyed 算法
- 最小生成树
- Prim算法
- Kruskal算法
- 最近公共祖先 (LCA)
- 二分图匹配
- 网络流
- 其他
- 莫队