开头是一个悲伤的故事。
要求:输入为两行,第一行为一个数字,第二行为用逗号分隔的数组,表示一个树的广度优先遍历。如下所示。
10
1,2,3,4,5
然后在上面实现要求,要求先不表。因为我连在C++中要怎么读入这样的数据都不会,都不会呀!还实现个毛毛!!!
两个问题:
1. 怎么判断到第二行没?
答:第一行为一个数,直接用cin读入赋值就好。
2. 数组里有几个数母鸡呀?
答:读入一行数,使用vector,把每个数分别存入。那么问题来了,C++里只能读入一行字符串呀,不过有stringstream类型可以将用空格分隔的数分别取出来。那么对读入的这一行用‘,’分隔的字符串,首先要做的就是把','替换为空格,然后转换为stringstream类型处理。
代码如下:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
int main()
{
int num;
string line;
vector<int> tree;
cin >> num;
//用cin.get()处理,才不影响接下来的对一行的操作
cin.get();
getline(cin,line); //将一行数据赋给字符串line
replace(line.begin(), line.end(), ',', ' '); //将,替换为空格
stringstream stream(line); //将line转换为stringstream类型stream
while(stream>>num) //取出所有的整数存入vector。此处整数可以换为浮点数等其他类型
tree.push_back(num);
//输出验证
cout << num <<endl;
for(vector<int>::iterator iter=tree.begin();iter!=tree.end();++iter)
cout<<*iter<<" ";
cout << endl;
}
为什么不用如下的这段代码处理第二行数组中的数据呢?
<pre name="code" class="cpp"> int a;
while(cin >> a) {
tree.push_back(a);
cin.get();
}
因为cin在读入特定类型时会忽略空格,回车,制表符等分隔符,用cin.get()吃掉数字之后的符号,不论用什么分隔符,都可以成功将数字存入vector,但由于最后的结束符被忽略,无法判断输入是否结束,只能使用 ctrl+Z 强制结束。
因此,使用getline读入一行字符串可以很好地解决这个问题,不用判断一行到底什么时候结束,而是将这一行直接取出。
getline可以跟第三个参数表示以该参数结尾。
如getline(cin, line, '\')表示以\结尾。
replace()函数包含在<algorithm>头文件中,给定起始结束位置,被替换和替换符号,即可实现替换。
line转换为stringstream类型也可由如下代码实现:
stringstream stream;
stream << line;
stringstream可以忽略像空格,制表符这样的分隔符,取出特定类型的数。如解决下面的问题:
一行double带小数点的数字,不定项数量,每个数字之间用不定项个空格隔开,以回车结束输入,放进一个vector里。
int main(){
string input;
vector<double> v;
getline(cin, input);
stringstream str(input);
double num;
while (str >> num) {
v.push_back(num);
}
//输出验证
cout << v.size() << endl;
for(vector<double>::iterator iter=v.begin();iter!=v.end();++iter)
cout<<*iter<<" ";
}
而使用如下的方法就要用ctrl+Z强制结束
int main(){
vector<double> v;
for (double d; cin >> d; v.push_back(d)){}
cout << v.size() << endl;
}
可以stringstream的这一特性进行数据类型的转换
int i;
string str;
//注意:如果做多次数据转换;必须调用clear()来设置转换模式
ss_stream << "456";
ss_stream >> i; // 首先将字符串转换为int
ss_stream.clear();
ss_stream << true;
ss_stream >> i; // 然后将bool型转换为int;假如之前没有做clear,那么i会出错
可以将字符串转换为int型456,将bool型装换为int型1
标准输入读入,每行加行号输出
int main(){
int line = 1;
string str;
while(getline(cin, str)) {
cout << line++ << " " << str << endl;
}
return 0;
}
Oh!多么好用的getline()和stringstream呀!可惜只是简单地学会用这一点点~
参考:
http://10741357.blog.51cto.com/10731357/1703983
https://segmentfault.com/q/1010000004357985
https://blog.yangl1996.com/?p=226
http://www.programgo.com/article/41762737095/