Java有一个方便的分割方法:

String str = "The quick brown fox";
String[] results = str.split(" ");

在c++中有简单的方法来做到这一点吗?


当前回答

我知道这个问题已经有了答案,但我想有所贡献。也许我的解决方案有点简单,但这就是我想到的:

vector<string> get_words(string const& text, string const& separator)
{
    vector<string> result;
    string tmp = text;

    size_t first_pos = 0;
    size_t second_pos = tmp.find(separator);

    while (second_pos != string::npos)
    {
        if (first_pos != second_pos)
        {
            string word = tmp.substr(first_pos, second_pos - first_pos);
            result.push_back(word);
        }
        tmp = tmp.substr(second_pos + separator.length());
        second_pos = tmp.find(separator);
    }

    result.push_back(tmp);

    return result;
}

如果在我的代码中有更好的方法,或者有什么错误,请评论。

更新:添加通用分隔符

其他回答

pystring是一个小型库,实现了Python的一系列字符串函数,包括split方法:

#include <string>
#include <vector>
#include "pystring.h"

std::vector<std::string> chunks;
pystring::split("this string", chunks);

// also can specify a separator
pystring::split("this-string", chunks, "-");

这是一个非常简单的问题:

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

vector<string> split(const char *str, char c = ' ')
{
    vector<string> result;

    do
    {
        const char *begin = str;

        while(*str != c && *str)
            str++;

        result.push_back(string(begin, str));
    } while (0 != *str++);

    return result;
}

我一直在寻找一种用任意长度的分隔符分割字符串的方法,所以我从头开始编写它,因为现有的解决方案不适合我。

这是我的小算法,只使用STL:

//use like this
//std::vector<std::wstring> vec = Split<std::wstring> (L"Hello##world##!", L"##");

template <typename valueType>
static std::vector <valueType> Split (valueType text, const valueType& delimiter)
{
    std::vector <valueType> tokens;
    size_t pos = 0;
    valueType token;

    while ((pos = text.find(delimiter)) != valueType::npos) 
    {
        token = text.substr(0, pos);
        tokens.push_back (token);
        text.erase(0, pos + delimiter.length());
    }
    tokens.push_back (text);

    return tokens;
}

据我测试,它可以与任何长度和形式的分离器一起使用。用string或wstring类型实例化。

该算法所做的就是搜索分隔符,获取到分隔符的字符串部分,删除分隔符并再次搜索,直到再也找不到它为止。

希望能有所帮助。

c++标准库算法普遍基于迭代器,而不是具体的容器。不幸的是,这使得在c++标准库中很难提供类似java的split函数,尽管没有人认为这很方便。但是它的返回类型是什么呢?std::向量< std:: basic_string <…> >吗?也许吧,但这样我们就被迫执行(可能是冗余的和昂贵的)分配。

相反,c++提供了大量基于任意复杂的分隔符分割字符串的方法,但它们都没有像其他语言中那样封装得很好。各种各样的方法填满了整个博客文章。

在最简单的情况下,你可以使用std::string::find进行迭代,直到你击中std::string::npos,然后使用std::string::substr提取内容。

一个更流畅的(和惯用的,但基本的)版本在空格上拆分将使用std::istringstream:

auto iss = std::istringstream{"The quick brown fox"};
auto str = std::string{};

while (iss >> str) {
    process(str);
}

使用std::istream_iterators,还可以使用vector的迭代器范围构造函数将string流的内容复制到vector中。

多个库(如Boost.Tokenizer)提供特定的标记器。

更高级的分裂需要正则表达式。c++特别为此提供了std::regex_token_iterator:

auto const str = "The quick brown fox"s;
auto const re = std::regex{R"(\s+)"};
auto const vec = std::vector<std::string>(
    std::sregex_token_iterator{begin(str), end(str), re, -1},
    std::sregex_token_iterator{}
);

我知道你想要一个c++的解决方案,但你可能会认为这是有帮助的:

Qt

#include <QString>

...

QString str = "The quick brown fox"; 
QStringList results = str.split(" "); 

在这个例子中,与Boost相比的优势在于,它直接一对一地映射到你的文章代码。

详见Qt文档