c++ 字串分割函式 stringsplit
阿新 • • 發佈:2022-05-19
新版:
/* stringsplit.hpp sdragonx 2006-06-16 00:43:16 revise 2018/7/28 19:42 function list: size_t stringsplit(container, const char_type*, size_t, char_type, bool) size_t stringsplit(container, const char_type*, size_t, const char_type*, size_t, bool) 這是個模板函式,支援標準庫裡面的各種容器,和標準字串。 這次更新,為了平臺相容性,削減到只剩兩個核心函式。 測試了3款編譯器,編譯通過 (gcc7.2.0、c++builder6.0、C++Builder2010) 例如: std::string s = "abc,,123"; std::vector<std::string> ls; stringsplit(ls, s.c_str(), s.length(), ',', true); 如果repeat == true,s就被分割成為3個字串,第二個字串是空的 如果repeat == false,s就被分割成2個字串 支援多個分割符: std::string s = "abc,|123|456"; std::string spliter = ",|"; std::vector<std::string> ls; stringsplit(ls, s.c_str(), s.length(), spliter.c_str(), spliter.size(), true); 也支援其他容器,例如: std::list<std::string> ls; stringsplit(ls, s.c_str(), s.size(), ',', true); std::deque<std::string> ls; stringsplit(ls, s.c_str(), s.size(), ',', true); 基礎的兩個函式,是以C字串格式寫的,也支援其他型別的字串, 只要這個字串有建構函式String(const char*, size_t length)就行 const char* s = "a,b,,c"; std::vector<std::string> ls; stringsplit(ls, s, strlen(s), ',', true);*/ #ifndef STRINGSPLIT_HPP_200606161656 #define STRINGSPLIT_HPP_200606161656 #include <algorithm> namespace cgl{ // // size_t stringsplit<char_type>(container, const char_type*, size_t, char_type, bool) // template<typename char_type, class container> size_t stringsplit( container& ls,const char_type* str, size_t size, char_type spliter, bool repeat = true) { typedef const char_type* const_iterator; typedef typename container::value_type string_type; const_iterator begin = str; const_iterator end = begin + size; const_iterator first = begin; const_iterator second;for( ; first<end; ) { second = std::find<const_iterator>(first, end, spliter); if(first == second){ if(repeat)ls.push_back(string_type()); } else{ ls.push_back(string_type(first, second - first)); } first = second+1; } if(repeat) { if(second == end-1){ ls.push_back(string_type()); } } return ls.size(); } // // size_t stringsplit<char_type>(container, const char_type*, size_t, const char_type*, size_t, bool) // template<typename char_type, typename container> size_t stringsplit(container& ls, const char_type* str, size_t size, const char_type* spliter, size_t spliter_size, bool repeat = true) { typedef typename container::value_type string_type; typedef const char_type* const_iterator; const_iterator end = str + size; const_iterator first = str; const_iterator second; for( ; first<end; ) { second = std::find_first_of<const_iterator>(first, end, spliter, spliter + spliter_size); if(first == second){ if(repeat)ls.push_back(string_type()); } else{ ls.push_back(string_type(first, second)); } first = second+1; } if(repeat) { if(second == end-1){ ls.push_back(string_type()); } } return ls.size(); } /* 以下擴充套件函式作為參考 有的平臺std::iterator是一個類,有點就是char*指標 各個平臺實現方式不一樣,暫時無法統一 // // size_t stringsplit<string_type>(container, const_iterator, const_iterator, char_type, bool) // template<typename string_type, typename container> size_t stringsplit( container& ls, typename string_type::const_iterator begin, typename string_type::const_iterator end, typename string_type::value_type spliter, bool repeat = true) { return stringsplit(ls, &*begin, end - begin, spliter, repeat); } // // size_t stringsplit<string_type>(container, string_type, char, bool) // template<typename string_type, typename container> size_t stringsplit( container& ls, const string_type& str, typename string_type::value_type spliter, bool repeat = true) { return stringsplit(ls, str.c_str(), str.size(), spliter, repeat); } // // size_t stringsplit<string_type>(container, const_iterator, const_iterator, const_iterator, const_iterator, bool) // template<typename string_type, typename container> size_t stringsplit( container& ls, typename string_type::const_iterator begin, typename string_type::const_iterator end, typename string_type::const_iterator spliter_begin, typename string_type::const_iterator spliter_end, bool repeat = true) { return stringsplit(ls, &*begin, end - begin, &*spliter_begin, spliter_end - spliter_begin, repeat); } // // size_t stringsplit<string_type>(container, string_type, string_type, bool) // template<typename string_type, typename container> size_t stringsplit( container& ls, const string_type& str, const string_type& spliter, bool repeat = true) { return stringsplit(ls, str.c_str(), str.size(), spliter.c_str(), spliter.size(), repeat); } */ }; // end namespace cgl; #endif //STRINGSPLIT_HPP_200606161656
以前的舊版:
/* stringsplit.hpp sdragonx 2006-06-16 00:43:16 revise 2016.07.18 19:04 */ #ifndef STRINGSPLIT_HPP_200606161656 #define STRINGSPLIT_HPP_200606161656 #include <algorithm> namespace cgl{ template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit( container< string_type<char_type> >& ls, typename string_type<char_type>::const_iterator begin, typename string_type<char_type>::const_iterator end, char_type spliter, bool repeat = true) { if(end <= begin) { return 0; } typename string_type<char_type>::const_iterator first = begin; typename string_type<char_type>::const_iterator second; for( ; first<end; ) { second = std::find<string_type<char_type>::const_iterator>(first, end, spliter); if(first == second){ if(repeat)ls.push_back(string_type<char_type>()); } else{ ls.push_back(string_type<char_type>(first, second)); } first = second+1; } if(repeat) { if(second == end-1){ ls.push_back(string_type<char_type>()); } } return ls.size(); } template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit( container< string_type<char_type> >& ls, typename string_type<char_type>::const_iterator begin, typename string_type<char_type>::const_iterator end, typename string_type<char_type>::const_iterator spliter_begin, typename string_type<char_type>::const_iterator spliter_end, bool repeat = true) { if(end <= begin || spliter_end<=spliter_begin) { return 0; } typename string_type<char_type>::const_iterator first = begin; typename string_type<char_type>::const_iterator second; for( ; first<end; ) { second = std::find_first_of<string_type<char_type>::const_iterator>(first, end, spliter_begin, spliter_end); if(first == second){ if(repeat)ls.push_back(string_type<char_type>()); } else{ ls.push_back(string_type<char_type>(first, second)); } first = second+1; } if(repeat) { if(second == end-1){ ls.push_back(string_type<char_type>()); } } return ls.size(); } template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit(container< string_type<char_type> > &strs, const string_type<char_type>& str, char_type spliter, bool repeat = true) { return stringsplit(strs, str.begin(), str.end(), spliter, repeat); } template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit(container< string_type<char_type> > &strs, const char_type* str, size_t length, char_type spliter, bool repeat = true) { return stringsplit(strs, str, str+length, spliter, repeat); } template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit(container< string_type<char_type> > &strs, const string_type<char_type>& str, const string_type<char_type>& spliter, bool repeat = true) { return stringsplit(strs, str.begin(), str.end(), spliter.begin(), spliter.end(), repeat); } template<typename char_type, template<typename> class string_type, template<typename> class container> size_t stringsplit(container< string_type<char_type> > &strs, const char_type* str, size_t length, const char_type* spliter, size_t splength, bool repeat = true) { return stringsplit(strs, str, str+length, spliter, spliter+splength, repeat); } }; // end namespace cgl; #endif //STRINGSPLIT_HPP_200606161656