从字符串读入stringstream

时间:2014-02-04 14:54:36

标签: c++ string stringstream

当我尝试从字符串中解析空白分隔的double值时,我发现了这种奇怪的行为,即以循环方式读出字符串。

以下是该计划:

stringstream ss;
string s("1 2 3 4");
double t;
list<double> lis;

for(int j=0; j!=10; ++j){
    ss << s;
    ss >> t;
    lis.push_back(t);
}

for(auto e : lis){
    cout << e << " ";
}

这里输出:

1 2 3 41 2 3 41 2 3 41

如果我将尾随空格追加为s= "1 2 3 4 ";,我会

1 2 3 4 1 2 3 4 1 2 

现在问题:
1)如果我不知道字符串s中有多少条目,我如何读入列表中的所有条目? 2)operator<<ss << s;实际上是谁// declarations as before ss << s; while(ss >> t){ lis.push_back(t); } // output as before ?是否指定循环阅读?
3)我可以更好地解析吗?

谢谢!


这是固定代码(感谢timrau):

 1 2 3 4  

这会产生:

stringstream

根据需要。 (在处理下一个输入之前,不要忘记通过ss.clear()清除{{1}} .;))

来自HeywoodFloyd的另一个有用的评论:还可以使用boost / tokenizer“分割”字符串,请参阅this post

3 个答案:

答案 0 :(得分:7)

您可以测试>>的返回值。

while (ss >> t) {
    lis.push_back(t);
}

没有指定循环阅读。它是ss << s"1 2 3 4"附加到流的末尾。

在第一轮之前:

""

在第一次ss << s之后:

"1 2 3 4"

在第一次ss >> t之后:

" 2 3 4"

第二次ss << s之后:

" 2 3 41 2 3 4"

如果1 2 3 41 2 3 41 2 3 41中没有尾随空格,那么很明显为什么会得到s

答案 1 :(得分:0)

然后使用s.length()表示包含未知数量条目的字符串,如果您使用您的方法。 或者,正如timrau所建议的那样,只需初始化一次你的字符串流。

stringstream ss;
string s("1 2 3 4 5 6 7 8");
ss << s;
double t;
list<double> lis;
while (ss >> t) {
    lis.push_back(t);
}

for(auto e : lis){
    cout << e << " ";
}

答案 2 :(得分:0)

This stackoverflow post包含一个boost tokenizer示例。您可能希望将字符串标记化并以这种方式迭代它。这将解决timrau指出的无尾随空间问题。