標籤:

C++ 的 string 為什麼不提供 split 函數?


2015-10-19

我的幾點顧慮:

0. 要不要堅持 D 的領導(誤

1. 返回的容納 tokens 的容器應該是啥?vector?list?

2. 資不資瓷一個 RE 作為分隔符?

3. 既然有 split 了,要不要提供 join?

QString 的 split 提供了如下幾種重載形式:

QStringList QString::split(const QString sep, SplitBehavior behavior = KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

QStringList QString::split(QChar sep, SplitBehavior behavior = KeepEmptyParts, Qt::CaseSensitivity cs = Qt::CaseSensitive) const;

QStringList QString::split(const QRegExp rx, SplitBehavior behavior = KeepEmptyParts) const;

倘若要給 std::string 添加一個 split 介面,QString::split 對我們有怎樣的啟發呢?

當然,下面這個帖子討論得更詳細:

c++ - Why doesn"t std::string contain a split() method?

說白了。實現一個 split 可能是一個可大可小的問題。有的人可能只需要用特定字元作為分隔符就夠了,那麼:

Split a string in C++? Splitting a C++ std::string using tokens, e.g. ";"

可能就滿足需求了。

而更複雜的需求,考量的東西也會多一些。

2016-09-27

Boost 庫提供了 split、join:& 。其中,join 的實現依賴於 Boost.Range。但是直到 C++11 C++ 標準庫還未提供 range 實現。這裡是一個提案:GitHub - ericniebler/range-v3: Experimental range library for C++11/14/17。

2016-11-26T18:49+08:00

https://github.com/myd7349/Ongoing-Study/blob/master/cpp/split.hpp

2017-10-15T14:07+08:00

https://github.com/abseil/abseil-cpp/blob/master/absl/strings/str_split.h

----


split得到的是一個vector,如果增加split函數的話,string和vector耦合了,私以為是這個原因


來自stack over flow

For what it"s worth, here"s another way to extract tokens from an input string, relying only on standard library facilities. It"s an example of the power and elegance behind the design of the STL.

#include &
#include &
#include &
#include &
#include &

int main() {
using namespace std;
string sentence = "And I feel fine...";
istringstream iss(sentence);
copy(istream_iterator&(iss),
istream_iterator&(),
ostream_iterator&(cout, "
"));
}

Instead of copying the extracted tokens to an output stream, one could insert them into a container, using the same generic copy algorithm.

vector& tokens;
copy(istream_iterator&(iss),
istream_iterator&(),
back_inserter(tokens));

... or create the vector directly:

vector& tokens{istream_iterator&{iss},
istream_iterator&{}};

Split a string in C++?


主要是因為Split存在太(nao)多(can)的選(yao)擇(qiu),所以乾脆就不提供了。

概括起來就是:媽的免費的庫還這麼多要求,這麼逼逼爺還不樂意給你做了!


stl雖然有些瑕疵,但和其他語言的庫相比堪稱藝術品。提供哪些函數不提供哪些函數是經過精心選擇的。對於容器來說,有一個基本原則是,如果某個操作實現為容器類的成員函數並不能獲得優勢,那麼就不提供。你看vector沒有find但是set有。因為set的find是Ologn,而stdfind是On。


因為那個年代大家沒有意識到string_ref的重要性


支持split的話,不管返回什麼,都是要分配新內存的。然而C++的運行環境都不見得能保證有new/malloc這類函數,更不要提vector這麼重的庫了。附加split會產生很強的平台要求,這個與C++一直強調輕平台可裁剪的思路是背道而馳的。所以至今沒有內置split,而是通過第三方庫或者boost這類准第三方庫提供。


std:string提供的方法不是不夠而是太多了。


#include &

#include &

有大量的函數可供選擇,很容易就組裝出一個split

你也可以使用regex


c++沒提供的東西很多,就是懶得沒實現,一群人還能藝術的角度洗地,也是醉了。


http://www.cplusplus.com/faq/sequences/strings/split/#basic-algorithm

這個也許對你有些幫助,我不確定。


1.Split a string in C++? handle whitespace characters
2.Splitting a C++ std::string using tokens, e.g. quot;;quot; handle single delimiter character

3.regex handle specific substring as the delimiter


可以使用std:string的find和substring組裝,個人感覺如果有spilt,返回的應該是vector的string,估計設計者不想這樣


我這裡有寫關於它的一點點見解 C++ split()函數的實現


看了oc裡面nsstring的介面部分。我個人認為,簡潔是一種美


boost string algorithm


還是效率問題,有的人需要效率有的人需要安全,場景太不一樣,乾脆先不弄呢。

估計等 string_view 出來之後有望搞兩個 split 方法。


strtok

孱弱了點,將就一下吧


boost::split


C++的string是全世界最難用的字元串,難用到了腦殘的程度。

格式化沒有,大小寫轉換沒有,分割沒有,replace沒有,trim沒有,join沒有,數字字元串來迴轉換別的所有語言都是一行C++要3行……

我實在想不出這玩意跟vector&有啥區別。

要說string最有用的函數那就是c_str,然後轉成C字元串來用。


std::vector& Split(const std::string s, const std::string delim)
{
std::vector& v;

if (!delim.empty())
{
auto b = s.begin();
auto i = s.end();
while ((i = std::search(b, s.end(), delim.begin(), delim.end())) != s.end())
{
if (i - b &> 0) // token can"t be empty string
{
v.emplace_back(std::string(b, i));
}

b = i + delim.length();
}

if (b != s.end())
{
v.emplace_back(std::string(b, s.end()));
}
}
else
{
throw "Delimiter can"t be empty string";
}

return v;
}

int main()
{
std::string s("a split string test");
auto v = Split(s, " ");

for each (auto var in v)
{
std::cout &<&< var &<&< " "; } return 0; }


我覺得可能是因為在cstring中定義了std::strtok吧,雖然用起來比直接提供split函數麻煩,但是功能是一致的,所以再提供一個split函數造成了功能上的冗餘?


推薦閱讀:

C++函數返回值拷貝問題?
operator=重載時,是否可以用一個按值傳遞版本取代按const引用傳遞和右值引用傳遞?
關於C++右值及std::move()的疑問?
C++11 中 typedef 和 using 有什麼區別?
C++中如下的變數聲明見過嗎?
auto recommended = 200"000U;

TAG:C |