Ali*_*Ali 39 c++ string algorithm
我知道这是一个非常容易的问题,但我只想一劳永逸地解决这个问题
我只想使用字符作为拆分分隔符将字符串拆分为数组.(很像C#着名的.Split()函数.我当然可以应用蛮力方法,但我想知道是否还有更好的方法.
到目前为止,我已经搜索过,可能最接近的解决方案方法是使用strtok(),但由于它的不便(将字符串转换为字符数组等),我不喜欢使用它.有没有更简单的方法来实现这个?
注意:我想强调这一点,因为人们可能会问"蛮力怎么行不通".我的强力解决方案是创建一个循环,并使用里面的substr()函数.但是,由于它需要起点和长度,因此当我想分割日期时它会失败.因为用户可能会在7/12/2012或07/3/2011输入它,在计算"/"分隔符的下一个位置之前,我可以真正地告诉它长度.
小智 81
使用向量,字符串和字符串流.有点麻烦,但它的确如此.
std::stringstream test("this_is_a_test_string");
std::string segment;
std::vector<std::string> seglist;
while(std::getline(test, segment, '_'))
{
seglist.push_back(segment);
}
Run Code Online (Sandbox Code Playgroud)
这导致具有相同内容的向量
std::vector<std::string> seglist{ "this", "is", "a", "test", "string" };
Run Code Online (Sandbox Code Playgroud)
Ben*_*ell 13
另一种方式(C++ 11/boost)适合喜欢RegEx的人.就我个人而言,我是这种数据的忠实粉丝.IMO它比使用分隔符简单地分割字符串要强大得多,因为如果您愿意,您可以选择更加智能地构建"有效"数据.
#include <string>
#include <algorithm> // copy
#include <iterator> // back_inserter
#include <regex> // regex, sregex_token_iterator
#include <vector>
int main()
{
std::string str = "08/04/2012";
std::vector<std::string> tokens;
std::regex re("\\d+");
//start/end points of tokens in str
std::sregex_token_iterator
begin(str.begin(), str.end(), re),
end;
std::copy(begin, end, std::back_inserter(tokens));
}
Run Code Online (Sandbox Code Playgroud)
chr*_*ock 11
Boost有你想要的split()algorithm/string.hpp
:
std::string sample = "07/3/2011";
std::vector<string> strs;
boost::split(strs, sample, boost::is_any_of("/"));
Run Code Online (Sandbox Code Playgroud)
Hum*_*ler 10
由于还没有人发布此内容:使用.c++20解决方案非常简单ranges
。您可以使用 astd::ranges::views::split
来分解输入,然后将输入转换为std::string
或std::string_view
元素。
#include <ranges>
...
// The input to transform
const auto str = std::string{"Hello World"};
// Function to transform a range into a std::string
// Replace this with 'std::string_view' to make it a view instead.
auto to_string = [](auto&& r) -> std::string {
const auto data = &*r.begin();
const auto size = static_cast<std::size_t>(std::ranges::distance(r));
return std::string{data, size};
};
const auto range = str |
std::ranges::views::split(' ') |
std::ranges::views::transform(to_string);
for (auto&& token : str | range) {
// each 'token' is the split string
}
Run Code Online (Sandbox Code Playgroud)
这种方法实际上可以组合成任何东西,甚至是一个split
返回 a 的简单函数std::vector<std::string>
:
auto split(const std::string& str, char delimiter) -> std::vector<std::string>
{
const auto range = str |
std::ranges::views::split(delimiter) |
std::ranges::views::transform(to_string);
return {std::ranges::begin(range), std::ranges::end(range)};
}
Run Code Online (Sandbox Code Playgroud)
我本质上不喜欢stringstream
,尽管我不确定为什么。今天,我编写了这个函数,允许将std::string
任意字符或字符串拆分为向量。我知道这个问题已经很老了,但我想分享一种替代的 split 方式std::string
。
此代码完全省略了从结果中分割的字符串部分,尽管可以轻松修改以包含它们。
#include <string>
#include <vector>
void split(std::string str, std::string splitBy, std::vector<std::string>& tokens)
{
/* Store the original string in the array, so we can loop the rest
* of the algorithm. */
tokens.push_back(str);
// Store the split index in a 'size_t' (unsigned integer) type.
size_t splitAt;
// Store the size of what we're splicing out.
size_t splitLen = splitBy.size();
// Create a string for temporarily storing the fragment we're processing.
std::string frag;
// Loop infinitely - break is internal.
while(true)
{
/* Store the last string in the vector, which is the only logical
* candidate for processing. */
frag = tokens.back();
/* The index where the split is. */
splitAt = frag.find(splitBy);
// If we didn't find a new split point...
if(splitAt == std::string::npos)
{
// Break the loop and (implicitly) return.
break;
}
/* Put everything from the left side of the split where the string
* being processed used to be. */
tokens.back() = frag.substr(0, splitAt);
/* Push everything from the right side of the split to the next empty
* index in the vector. */
tokens.push_back(frag.substr(splitAt+splitLen, frag.size()-(splitAt+splitLen)));
}
}
Run Code Online (Sandbox Code Playgroud)
要使用,只需像这样调用...
std::string foo = "This is some string I want to split by spaces.";
std::vector<std::string> results;
split(foo, " ", results);
Run Code Online (Sandbox Code Playgroud)
您现在可以随意访问向量中的所有结果。就这么简单 - 不stringstream
,没有第三方库,不会回到 C!