【问题标题】:Read from string into stringstream从字符串读取到字符串流
【发布时间】:2014-02-04 14:54:35
【问题描述】:

当我尝试从字符串中解析以空格分隔的双精度值时,我发现了这种奇怪的行为,即字符串是以循环方式读取的。

这是程序:

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 中有多少条目,如何将所有条目读入列表 l?
2)我实际上是在调用哪个operator&lt;&lt;ss &lt;&lt; s;?是否指定循环读取?
3)我可以以更好的方式进行解析吗?

已经谢谢了!


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

// declarations as before
ss << s;
while(ss >> t){
   lis.push_back(t);
}
// output as before  

这会产生:

 1 2 3 4  

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

HeywoodFloyd 的另一条有用评论:也可以使用 boost/tokenizer 来“拆分”字符串,参见 this post

【问题讨论】:

  • 您无需将s 多次放入流中。将ss &lt;&lt; s; 移到循环之外。

标签: c++ string stringstream


【解决方案1】:

可以测试&gt;&gt;的返回值。

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

没有指定循环读取。这是ss &lt;&lt; s"1 2 3 4" 附加到流的末尾。

第一个循环之前:

""

第一个ss &lt;&lt; s之后:

"1 2 3 4"

第一个ss &gt;&gt; t之后:

" 2 3 4"

第二次之后ss &lt;&lt; s:

" 2 3 41 2 3 4"

那么,如果s 中没有尾随空格,为什么会得到1 2 3 41 2 3 41 2 3 41 就很清楚了。

【讨论】:

  • 知道了!多谢。我在想&lt;&lt; 会像cin &gt;&gt; some_string 那样读取空格分隔的单词。
【解决方案2】:

然后使用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 << " ";
}

【讨论】:

    【解决方案3】:

    This stackoverflow post 包含一个 boost tokenizer 示例。您可能想要标记您的字符串并以这种方式遍历它。这将解决timrau 指出的无尾随空格问题。

    【讨论】:

      猜你喜欢
      • 2012-05-13
      • 2015-11-01
      • 2020-03-16
      • 2010-10-02
      • 2020-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多