如何在 C++ 中将空格分隔的字符串拆分为多个字符串?

Posted

技术标签:

【中文标题】如何在 C++ 中将空格分隔的字符串拆分为多个字符串?【英文标题】:How to split a space separated string into multiple strings in C++? 【发布时间】:2012-01-30 18:47:28 【问题描述】:

我的代码如下所示:

static int myfunc(const string& stringInput)

    string word;
    stringstream ss;

    ss << stringInput;
    while(ss >> word)
    
        ++counters[word];
    
    ...

这里的目的是获取一个输入字符串(用空格''分隔)到字符串变量word中,但是这里的代码似乎有很多开销——将输入字符串转换为字符串流和从字符串流中读取到目标字符串中。

有没有更优雅的方式来实现同样的目的?

【问题讨论】:

How to split a string in C++? 的可能重复项 我想这个问题已经被问过好几次了:***.com/questions/1894886/…***.com/questions/4328685/…***.com/questions/536148/…***.com/questions/1511029/…***.com/questions/3162108/… 谢谢您,sixletter 和 Jared。你的主题为我提供了很多关于这个主题的知识。抱歉,我在发帖之前没有在这个论坛上进行彻底的搜索。再次感谢! 【参考方案1】:
Code in c++
#include<sstream>
#include<vector>
using namespace std;    
string diskNames="vbbc anmnsa mansdmns";
string temp;
vector <string> cds;
stringstream s (diskNames);
while(s>> temp)
cds.push_back(temp);

【讨论】:

【参考方案2】:

在 Visual C++ 11 中,您可以使用 TR1 中的 regex_token_iterator。

sregex_token_iterator::regex_type white_space_separators("[[:space:]]+",regex_constants::optimize);

for(sregex_token_iterator i(s.begin(),s.()end,white_space_separators,-1),end; i!=end; i++)

 cout << *i << endl;
 // or use i.start, i.end which is faster access

如果您担心性能(以及字符串复制等开销),您可以编写自己的例程:

#include <ctype.h>

#include <string>
#include <iostream>
using namespace std;

int main()

 string s = "Text for tokenization  ";

 const char *start = s.c_str();
 const char *end = start + s.size();
 const char *token = start;

 while (start!=end)
 
   if(isspace(*start))
   
    if (token < start)
    
      // Instead of constructing string, you can 
      // just use [token,start] part of the input buffer
      cout << string(token,start) << ' ';
    

    start++;
    token = start;
   
   else
   
    start++;
   
  

 if (token < start)
 
    cout << string(token,start) << ' ';
 


【讨论】:

谢谢你,佩特罗。您的拆分例程与 Andrew Koenig 在他的“Accelerated C++”中的非常相似。两者都是不错的功能。【参考方案3】:

使用流迭代器和标准函数:

static int myfunc(std::string const& stringInput)

    std::stringstream ss(stringInput);

    std::for_each(std::istream_iterator<std::string>(ss),
                  std::istream_iterator<std::string>(),
                  [&counters](std::string const& word)  ++counters[word];
                 )
    ...

如果你没有 lambda 那么:

struct Helper

     void operator()(std::string const& word) const ++counters[word];
     Helper(CounterType& c) : counters(c) 
     CounterType& counters;
;

static int myfunc(std::string const& stringInput)

    std::stringstream ss(stringInput);

    std::for_each(std::istream_iterator<std::string>(ss),
                  std::istream_iterator<std::string>(),
                  Helper(counters)
                 )
    ...

【讨论】:

谢谢你,洛基。你的代码看起来很棒。不过,我更喜欢不涉及流的方式。 :-)【参考方案4】:

您在问如何拆分字符串。 Boost 有一个有用的实用程序 boost::split()

http://www.boost.org/doc/libs/1_48_0/doc/html/string_algo/usage.html#id3115768

这是一个将结果词放入向量的示例:

#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));

【讨论】:

谢谢,但如果可能的话,我打算放弃使用流。 谢谢你,亚历克斯。是的,这就是我想要的。但是我不确定我的g++编译器是否带有boost库,如何检查boost是否存在?顺便说一句,在编译源代码时使用任何额外的 -l 命令吗?如果没有可用的 boost,STL 中是否有类似的实用功能? 抱歉这里的忍者编辑。一开始我误解了你的问题。 顺便说一句,亚历克斯。只需在 Andrew Koenig 的经典“加速 C++”中找到另一个 split() 的实现。第 5 章的第 5.6 节(将字符串分开)中提供了实现。 @Qiang :您标记了自己的问题stream,但您试图避免流?这有点误导。【参考方案5】:

使用ostringstream,也许

istringstream(stringInput); // initialize with the string

【讨论】:

是的,这样可以节省一点。但是基本思路还是一样的:构造一个stringstream,然后从这个stream中读取。我们可以不使用streamstream吗?并且仍然将空格分隔的字符串读入word?

以上是关于如何在 C++ 中将空格分隔的字符串拆分为多个字符串?的主要内容,如果未能解决你的问题,请参考以下文章

如何基于多个空格字符将文本文件拆分为 2 列作为 scala spark 的分隔符

有没有一种简单的方法可以将由空格字符分隔的一行输入拆分为 C++ 中的整数?

如何拆分具有多个分隔符powershell的字符串?

如何在awk中将分隔字符串拆分为数组?

如何在 c++ 中将字符串拆分为左括号和右括号之间的字符串列表?

如何在 Rust 中将字符串拆分为块以插入空格