C++的string默认没有split函数,但是split函数又是如此常用,今天在网上查资料学习一下。
方法一:使用getline
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;
// 后面的代码中省略头文件和命名空间
int main()
{
string s = "Let me split this into words";
vector<string> v;
istringstream iss(s);
string token;
while(getline(iss, token, ' ')) {
v.push_back(token);
}
for(auto i : v) {
cout << i << endl;
}
return 0;
}
方法二:使用iterator
int main()
{
string s = "Let me split this into words";
istringstream iss(s);
vector<string> result(istream_iterator<string>(iss), (istream_iterator<string>()));
for(auto i : result) {
cout << i << endl;
}
return 0;
}
有一点不理解的地方是(istream_iterator<string>())
为什么必须在外面加个括号,不加括号就会报错,这个问题先暂时搁在这。
方法三:
方法二性能不好的原因在于操作符<<
。除了在空格处停止,<<
操作符做了很多额外的操作,比如格式化,读写一些flags,构建对象等等,其实我们并不需要这些操作。
我们需要控制string
的<<
操作符的行为。实现这个目的有多种方法,这里我们选择继承string
类型。
class WordDelimitedByComma : public string
{};
istream& operator >> (istream& is, WordDelimitedByComma& output) {
getline(is, output, ',');
return is;
};
int main()
{
string s = "Let,me,split,this,into,words";
istringstream iss(s);
vector<string> result(istream_iterator<WordDelimitedByComma>(iss), (istream_iterator<WordDelimitedByComma>()));
for(auto i : result) {
cout << i << endl;
}
return 0;
}
更加完善的做法是使用模板类,可以用来选择不同的分隔符。
template<char T>
class WordDelimitedByComma : public string
{};
template<char T>
istream& operator >> (istream& is, WordDelimitedByComma<T>& output) {
getline(is, output, T);
return is;
};
int main()
{
string s = "Let,me,split,this,into,words";
istringstream iss(s);
vector<string> result(istream_iterator<WordDelimitedByComma<','>>(iss), (istream_iterator<WordDelimitedByComma<','>>()));
for(auto i : result) {
cout << i << endl;
}
return 0;
}
暂时先用这三种方法就能满足平时的需要。个人觉得方法一用起来更加方便一些。
参考:
https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/
网友评论