c++字串分割的方法
C++ 中經常需要對字串按照分隔符進行分割以獲得子串序列,子串的順序與其在原字串中出現的順序一致。一般有兩種需求場景:
(1)給定一個分隔符(單個字元或子串)分割字串;
(2)給定一個或多個分隔符(單個字元),分割字串。
當給定的分隔符不在原字串中,則原字串不被分割,返回單個元素為原字串的 vector。
注意,本文實現時,如果被分割後的子串為空串,則不計入最終的子串序列。比如原字串是"a,b",分隔符為",",那麼分割後的子串序列為 [“a”,“b”],而不是 [“a”,“”,“b”]。
1.單個分隔符(單個字元或子串)分割字串
#include <iostream> #include <vector> #include <string> using namespace std; //@brief: 指定單個分隔符(單個字元或子串)分割字串 //@param: src 原字串;delimiter 分隔符,單個字元或子串 vector<string> splitStr(const string& src,const string& delimiter) { std::vector<string> vetStr; // 入參檢查 // 1.原字串為空或等於分隔符,返回空 vector if (src == "" || src == delimiter) { return vetStr; } // 2.分隔符為空返回單個元素為原字串的 vector if (delimiter == "") { vetStr.push_back(src); return vetStr; } string::size_type startPos = 0; auto index = src.find(delimiter); while (index != string::npos) { auto str = src.substr(startPos,index - startPos); if (str != "") { vetStr.push_back(str); } startPos = index + delimiter.length(); index = src.find(delimiter,startPos); } // 取最後一個子串 auto str = src.substr(startPos); if (str != "") { vetStr.push_back(str); } return vetStr; }
測試如下:
int main(int argc,char* argv[]) { string str = "I,love,China"; // 正常分割 auto vetStr = splitStr(str,","); cout << "vetStr.size() = " << vetStr.size() << endl; for (auto v : vetStr) { cout << v << " "; } // 邊界測試 vetStr = splitStr(str,"I,"); cout << endl << "vetStr.size() = " << vetStr.size() << endl; for (auto v : vetStr) { cout << v << " "; } // 不包含分隔符 vetStr = splitStr(str,"what"); cout << endl << "vetStr.size() = " << vetStr.size() << endl; for (auto v : vetStr) { cout << v << " "; } return 0; }
輸出結果:
vetStr.size() = 3
I love China
vetStr.size() = 1
love,China
vetStr.size() = 1
I,China
2.單個或多個分隔符(單個字元)分割字串
實現和單個分隔符(單個字元或子串)分割字串基本一致,關鍵地方是將獲取分隔符下標的函式由 std::string::find(…) 改為 std::string::find_first_of(…)。二者的區別如下:
std::string::find(...)
將分隔符看作一個整體在原字串中查詢並返回匹配的下標,比如 string("I love China").find("love") 返回 2。std::string::find_first_of(...)
在字串中搜索分隔符中任意一個字元出現的第一個位置。與 std::string::find(...) 的區別是不需要整個分隔符匹配,只需要分隔符中的單個字元匹配即可。
具體實現如下:
//@brief: 指定單個或多個分隔符(單個字元)分割字串 //@param: src 原字串;delimiter 單個或多個分隔符(單個字元) vector<string> splitStr(const string& src,const string& delimiter) { std::vector<string> vtStr; // 入參檢查 // 1.原字串為空返回空 vector if (src == "") { return vtStr; } // 2.分隔符為空返回單個元素為原字串的 vector if (delimiter == "") { vtStr.push_back(src); return vtStr; } string::size_type startPos = 0; auto index = src.find_first_of(delimiter); while (index != string::npos) { auto str = src.substr(startPos,index - startPos); if (str != "") { vtStr.push_back(str); } startPos = index + 1; index = src.find_first_of(delimiter,startPos); } // 取最後一個子串 auto str = src.substr(startPos); if (str != "") { vtStr.push_back(str); } return vtStr; }
測試如下:
int main(int argc,China"; // 正常分割。按照 h 與逗號分割 auto vetStr = splitStr(str,"h,"Ia"); cout << endl << "vetStr.size() = " << vetStr.size() << endl; for (auto v : vetStr) { cout << v << " "; } // 不包含分隔符 vetStr = splitStr(str,"_:"); cout << endl << "vetStr.size() = " << vetStr.size() << endl; for (auto v : vetStr) { cout << v << " "; } return 0; }
輸出結果:
vetStr.size() = 4
I love C ina
vetStr.size() = 1
,Chin
vetStr.size() = 1
I,China
3.反面例項
下面是我情急之下實現的單個或多個分隔符(單個字元)分割字串的函式,有點“髒亂差”,作為反面教材,希望能夠幫助大家時刻記住程式碼的簡潔與優雅是多麼可貴,大家可以對比感受一下。另外,適當的程式碼註釋,對提高程式碼的可讀性會有很大幫助。
髒亂差版本一:
//qsort函式需要的比較函式,按照升序排序 int comp(const void*a,const void*b) { return *(int*)a-*(int*)b; } //@brief: 指定單個或多個分隔符(單個字元)分割字串 //@param: src 原字串;delimiter 分隔符集合 vector<string> splitStr(const string& src,const string& delimiter) { vector<string> strRes; int maxSubstrNum=src.size(); int* pos=new int[maxSubstrNum]; memset(pos,maxSubstrNum*sizeof(int)); int j=0; for(size_t i=0;i<delimiter.size();++i) { string::size_type index=src.find(delimiter[i]); while(index!=string::npos) { pos[j++]=index; index=src.find(delimiter[i],index+1); } } //排序 qsort(pos,j,sizeof(int),comp); //取出第一個子串 string substrFir=src.substr(0,pos[0]); if(substrFir!="") strRes.push_back(substrFir); //取出中間j-1個子串 for(int i=0;i<j-1;++i) { string substr=src.substr(pos[i]+1,pos[i+1]-pos[i]-1); if(substr!="") { strRes.push_back(substr); } } //取出最後一個子串 string substrLast=src.substr(pos[j-1]+1,src.size()-pos[j-1]-1); if(substrLast!="") { strRes.push_back(substrLast); } delete[] pos; return strRes; }
程式碼主要說明:
(1)利用 find() 和 substr() 函式實現分割功能;
(2)程式碼中,需要對分割符出現的下標進行排序,這樣才能順序取出子串。
髒亂差版本二:
//@brief: 指定單個或多個分隔符(單個字元)分割字串 //@param: src 原字串;delimiter 分隔符集合 std::vector<std::string> splitStr(const std::string &sStr,const std::string &sSep) { std::vector<std::string> vt; std::string::size_type pos = 0; std::string::size_type pos1 = 0; int pos_tmp = -1; while(true) { std::string s; std::string s1; pos1 = sStr.find_first_of(sSep,pos); if(pos1 == std::string::npos) { if(pos + 1 <= sStr.length()) { s = sStr.substr(-1 != pos_tmp ? pos_tmp : pos); s1 = ""; } } else if(pos1 == pos && (pos1 + 1 == sStr.length())) { s = ""; s1 = ""; } else { s = sStr.substr(-1 != pos_tmp ? pos_tmp : pos,pos1 - (-1 != pos_tmp ? pos_tmp : pos)); s1 = sStr.substr(pos1 + 1); if (-1 == pos_tmp) { pos_tmp = pos; } pos = pos1; } if(!s.empty()) { vt.push_back(s); } pos_tmp = -1; if(pos1 == std::string::npos) { break; } pos++; } return vt; }
以上就是c++字串分割的方法的詳細內容,更多關於C++ 字串分割的資料請關注我們其它相關文章!