在算法竞赛中,有时会出现一些特殊的数据读入,比如每行的数据元素个数不确定,更复杂一些的是连续多行的数据个数不确定。单行的不确定元素个数的读入可以借助 w h i l e ( while( while(~ s c a n f ( ) ) scanf()) scanf())或 w h i l e ( c i n > > x ) while(cin>>x) while(cin>>x)等实现读入。复杂的是多行不连续。
有n行数据,每行数据个数不等,输出每行数据的平均值。
输入数据:
4
32 4 6
1 3 5 7 9 45 8
98 -9 2 2
7
-
借助getchar()函数实现,类似快读。
每行的末尾是换行符号"\n",可以判断是否读到该字符作为该行读入完毕的依据。 -
借助 s t r i n g s t r e a m stringstream stringstream。头文件 < s s t r e a m > <sstream> <sstream>。数据的输入输出流,操作的对象是string。工作原理可理解为:将string类型的数据放入输入流中,然后从数据流中向外输出数据。用法类似于cin。常见的应用有三种。
类型转换
// int -> string
stringstream sstream;
string strResult;
int nValue = 1000;
// 将int类型的值放入输入流中
sstream << nValue;
// 从sstream中抽取前面插入的int类型的值,赋给string类型
sstream >> strResult;
多字符串拼接
stringstream sstream;
// 将多个字符串放入 sstream 中
sstream << "first" << " " << "string,";
sstream << " second string";
// 可以使用 str() 方法,将 stringstream 类型转换为 string 类型;
cout << "strResult is: " << sstream.str() << endl;
清空流
// 清空 sstream 之 str("")
sstream.str("");
// 清空 sstream 之 clear() 方法
sstream.clear();
需要用 g e t l i n e ( ) getline() getline()读入完整的一行,该函数会把换行符读进来,但是保存的时候不会保存换行符。需要注意一点的是,如果使用该函数的时候,前面有换行,应该用 g e t c h a r ( ) getchar() getchar()中和掉换行符,要不然 g e t l i n e ( ) getline() getline()会读入该换行符而停止,不会读入下一行了,造成错误。此种错误比较隐秘。
#include<cstdio>
#include<iostream>
#include <string>
#include <sstream>
using namespace std;
string s;
stringstream ss;
int main()
{
int n, t, cnt;
double sum;
cin>>n;
getchar(); // 中和掉n后面的换行符,因为getline()会读入换行符
for (int i = 1; i <= n; ++i)
{
getline(cin, s);
ss.clear(); // 清空缓存
ss << s; // 输入到流中
sum = 0;
cnt = 0;
while (ss >> t)
{
sum += t; ++cnt;
}
printf("%.2lf\n", sum / cnt);
}
}
类似的用法还有sscanf和sprintf,C标准的字符串读写。只能读写固定的个数,不能用流的形式。
s s c a n f ( s t r , " 格式符 " , 变量地址列表 ) sscanf(str, "格式符", 变量地址列表) sscanf(str,"格式符",变量地址列表),从字符串 s t r str str中读取数据存到变量中,返回值是成功读取的数据个数。 s p r i n t f ( s t r , " 格式符 " , 变量列表 ) sprintf(str, "格式符", 变量列表) sprintf(str,"格式符",变量列表),将变量数据输出存储到字符串 s t r str str中,返回值是成功输出的数据个数。头文件 c s t d i o cstdio cstdio。
进一步的,如果是行数和每行的数据元素个数都不确定,怎么读入呢?可以用 w h i l e ( g e t l i n e ( c i n , s ) ) while (getline(cin, s)) while(getline(cin,s))。
#include<cstdio>
#include<iostream>
#include <string>
#include <sstream>
using namespace std;
string s;
stringstream ss;
int main()
{
int n, t, cnt;
double sum;
while (getline(cin, s))
{
ss.clear(); // 清空缓存
ss << s; // 输入到流中
sum = 0;
cnt = 0;
while (ss >> t)
{
sum += t; ++cnt;
}
printf("%.2lf\n", sum / cnt);
}
}
以上方法不仅适用于数字类型,字符串类型同样适用。区别是: g e t c h a r ( ) getchar() getchar()操作的对象是字符型数组, s t r i n g s t r e a m stringstream stringstream操作的对象是 s t r i n g string string数据类型。