C++標准庫中似乎沒有分割字符串的函數。自己實現了一個,上網搜索過程中同時還發現兩個比較有趣的分割方式。
1. 自己的簡單實現
1 void split(const char *s, vector<string> &strs, char delim = ' ') { 2 if(s == nullptr) { 3 return; 4 } 5 6 const char *head, *tail; 7 head = tail = s; 8 9 while(*head != '\0') { 10 while(*head != '\0' && *head == delim) { 11 head++; 12 } 13 14 tail = head; 15 while(*tail != '\0' && *tail != delim) { 16 tail++; 17 } 18 19 if(head != tail) { 20 strs.push_back(string(head, tail)); 21 head = tail; 22 } else { 23 break; 24 } 25 } 26 }
將字符串s按照delim代表的字符分割,並且放入vector<string>中。
搜索過程中在stackoverflow上,發現了另外兩個簡單明了的辦法。
2. 利用istringstream
1 int main() { 2 string sentence = "And I feel fine... asdf"; 3 istringstream iss(sentence); 4 vector<string> strs{istream_iterator<string>(iss), istream_iterator<string>()}; 5 for(auto &s: strs) { 6 cout << s << endl; 7 } 8 }
用字符串構造成字符串流,然后通過字符串流迭代器添加到vector中。
istream_iterator是使用空格進行分割的,所以這個方法的局限性就是沒法使用空格以外的字符進行分割字符串
3. 利用getline函數
void split(const std::string &s, std::vector<std::string> &elems, char delim = ' ') { std::stringstream ss; ss.str(s); std::string item; while (std::getline(ss, item, delim)) { elems.push_back(item); } } int main() { string line = "asd fasdf fadf fa"; vector<string> strs; split(line, strs); for(auto &s: strs) { cout << s << endl; } return 0; }
getline函數,顧名思義,是用來獲取一行數據的,不過它的第三個參數也可以修改成其他字符,這樣就可以將其他字符作為行分割符使用。
不過這種實現的缺點就是,getline每遇到一個行分割符都會返回一次,所以對於分割符連續的情況就束手無策了。
例如:
1 string line = "asd fasdf fadf fa";
打印結果就是:
asd
fasdf
fadf
fa