Kaip perjungti žodžius?

Bandau surūšiuoti eilutės žodžius.

Galima daryti prielaidą, kad eilutė susideda iš žodžių, atskirtų tarpais.

Atkreipkite dėmesį, kad nesu domina C eilutės funkcijos ar panašios manipuliacijos / prieiga prie simbolių. Be to, savo atsakyme pateikite pirmenybę elegancijai ir efektyvumui.

Geriausias sprendimas dabar yra:

 #include <iostream> #include <sstream> #include <string> using namespace std; int main() { string s = "Somewhere down the road"; istringstream iss(s); do { string subs; iss >> subs; cout << "Substring: " << subs << endl; } while (iss); } 

Ar yra elegantiškesnis būdas tai padaryti?

2749
25 окт. pateikė Ashwin Nanjappa spalio 25 d 2008-10-25 11:58 '08 at 11:58 2008-10-25 11:58
@ 76 atsakymai
  • 1
  • 2
  • 3

Už tai, ką kainuoja, yra dar vienas būdas ištraukti žetonų iš įvesties eilutės, remiantis tik standartinėmis bibliotekomis. Tai yra STL dizaino galios ir elegancijos pavyzdys.

 #include <iostream> #include <string> #include <sstream> #include <algorithm> #include <iterator> int main() { using namespace std; string sentence = "And I feel fine..."; istringstream iss(sentence); copy(istream_iterator<string>(iss), istream_iterator<string>(), ostream_iterator<string>(cout, "\n")); } 

Vietoj to, kad nukopijuotieji žetonai būtų nukopijuoti į išvesties srautą, galite juos įterpti į konteinerį, naudodami tą patį bendrojo copy algoritmą.

 vector<string> tokens; copy(istream_iterator<string>(iss), istream_iterator<string>(), back_inserter(tokens)); 

... arba sukurkite tiesiogiai vector :

 vector<string> tokens{istream_iterator<string>{iss}, istream_iterator<string>{}}; 
1241
26 окт. Zunino atsakymas spalio 26 d 2008-10-26 03:43 '08 at 3:43 2008-10-26 03:43

Aš naudoju tai atskirti eilutę pagal ribotuvą. Pirmieji rezultatai pasiekiami iš anksto sukonstruotame vektoriuje, antrasis grąžina naują vektorių.

 std::vector<std::string> x = split("one:two::three", ':'); 
2343
25 окт. atsakymą Evan Teran pateikė spalio 25 d. 2008-10-25 21:21 '08 at 9:21 pm 2008-10-25 21:21

Galimas sprendimas naudojant „Boost“ gali būti:

 #include <boost/algorithm/string.hpp> std::vector<std::string> strs; boost::split(strs, "string to split", boost::is_any_of("\t ")); 

Šis požiūris gali būti net greitesnis nei stringstream . Ir kadangi tai yra universalus šablono funkcija, jis gali būti naudojamas atskirti kitų tipų eilutes (wchar ir kt. Arba UTF-8), naudojant įvairius ribotuvus.

Daugiau informacijos žr.

810
25 окт. atsakymas pateikiamas ididak 25 oct. 2008-10-25 23:28 '08 at 11:28 2008-10-25 23:28
 #include <vector> #include <string> #include <sstream> int main() { std::string str("Split me by whitespaces"); std::string buf; // Have a buffer string std::stringstream ss(str); // Insert the string into a stream std::vector<std::string> tokens; // Create vector to hold our words while (ss >> buf) tokens.push_back(buf); return 0; } 
336
06 марта '11 в 8:52 2011-03-06 08:52 atsakymas pateikiamas pavasarį 06'11, 11:52 2011-03-06 08:52

Tiems, su kuriais tai nėra tinkama paaukoti visą kodo dydžio efektyvumą ir pamatyti „veiksmingą“ kaip elegancijos tipą, toliau turėtų būti saldus taškas (ir manau, kad konteinerių šablono klasė yra stebėtinai elegantiškas papildymas):

 template < class ContainerT > void tokenize(const std::string str, ContainerT tokens, const std::string delimiters = " ", bool trimEmpty = false) { std::string::size_type pos, lastPos = 0, length = str.length(); using value_type = typename ContainerT::value_type; using size_type = typename ContainerT::size_type; while(lastPos < length + 1) { pos = str.find_first_of(delimiters, lastPos); if(pos == std::string::npos) { pos = length; } if(pos != lastPos || !trimEmpty) tokens.push_back(value_type(str.data()+lastPos, (size_type)pos-lastPos )); lastPos = pos + 1; } } 

Paprastai aš naudoju std::vector<std::string> tipus kaip savo antrąjį parametrą ( ContainerT ) ... bet list<> greitesnis nei vector<> kai tiesioginė prieiga nėra reikalinga, ir jūs netgi galite sukurti savo eilutę klasė ir naudokite kažką panašaus į std::list<subString> , kur subString nepadaro neįtikėtino greičio kopijų.

Tai daugiau nei dvigubai greitesnis nei greičiausias šiame puslapyje ir beveik 5 kartus greičiau nei kiti. Be to, naudojant idealius parametrų tipus, galite pašalinti visas stygų ir sąrašų kopijas, kad padidintumėte greitį.

Be to, jis neatlieka (labai neveiksmingo) rezultato grąžinimo, o vietoj žetonų, kaip nuorodos, taip pat leidžia sukurti žetonų naudojimą keliais skambučiais, jei norite.

Galiausiai, galite nurodyti, ar iš tuščių žetonų išvalyti iš paskutinio pasirenkamo parametro.

Viskas, ko jam reikia, yra std::string ... kiti yra neprivalomi. Jis nenaudoja gijų arba skatinimo bibliotekos, tačiau yra pakankamai lankstus, kad natūraliai priimtų kai kuriuos iš šių užsienio tipų.

174
29 сент. Atsakymą Marius pateikia 29 sep. 2009-09-29 18:12 '09 18:12 2009-09-29 18:12

Čia yra dar vienas sprendimas. Tai pakankamai kompaktiškas ir efektyvus:

 std::vector<std::string> split(const std::string  char sep) { std::vector<std::string> tokens; std::size_t start = 0, end = 0; while ((end = text.find(sep, start)) != std::string::npos) { tokens.push_back(text.substr(start, end - start)); start = end + 1; } tokens.push_back(text.substr(start)); return tokens; } 

Ją galima lengvai suplanuoti, kad būtų galima valdyti eilių ribotuvus, platus eilutes ir pan.

Atkreipkite dėmesį, kad skilimas "" reiškia vieną tuščią eilutę ir skilimą "," (t. Y. Sep) sudaro dvi tuščios eilutės.

Ją taip pat galima lengvai panaudoti, jei norite praleisti tuščius žymas:

 std::vector<std::string> split(const std::string  char sep) { std::vector<std::string> tokens; std::size_t start = 0, end = 0; while ((end = text.find(sep, start)) != std::string::npos) { if (end != start) { tokens.push_back(text.substr(start, end - start)); } start = end + 1; } if (end != start) { tokens.push_back(text.substr(start)); } return tokens; } 

Jei praleidžiant tuščius žetonus reikia suskirstyti eilutę į kelis ribotuvus, ši versija gali būti naudojama:

 std::vector<std::string> split(const std::string text, const std::string delims) { std::vector<std::string> tokens; std::size_t start = text.find_first_not_of(delims), end = 0; while((end = text.find_first_of(delims, start)) != std::string::npos) { tokens.push_back(text.substr(start, end - start)); start = text.find_first_not_of(delims, end); } if(start != std::string::npos) tokens.push_back(text.substr(start)); return tokens; } 
155
13 сент. Aleco Thomas atsakymas Rugsėjo 13 d 2011-09-13 23:46 '11 11:46 PM 2011-09-13 23:46

Tai mano mėgstamiausias būdas kartoti per eilutę. Jūs galite padaryti viską, ką norite kiekvienam žodžiui.

 string line = "a line of text to iterate through"; string word; istringstream iss(line, istringstream::in); while( iss >> word ) { // Do something on `word` here... } 
111
25 окт. atsakymas pateikiamas gnomed 25 okt. 2008-10-25 12:16 '08, 12:16, 2008-10-25 12:16

Tai tarsi kamino perpildymo klausimas: kaip norėčiau pažymėti eilutę C + +? .

 #include <iostream> #include <string> #include <boost/tokenizer.hpp> using namespace std; using namespace boost; int main(int argc, char** argv) { string text = "token test\tstring"; char_separator<char> sep(" \t"); tokenizer<char_separator<char>> tokens(text, sep); for (const string t : tokens) { cout << t << "." << endl; } } 
78
25 окт. atsakymas duotas Ferruccio 25 okt. 2008-10-25 13:58 '08, 13:58 pm 2008-10-25 13:58

Man patinka tai, kad jis pateikia rezultatus vektoriuje, palaiko seką kaip separatorių ir suteikia galimybę kontroliuoti nulinės vertės išsaugojimą. Bet tai nėra tokia gera.

 #include <ostream> #include <string> #include <vector> #include <algorithm> #include <iterator> using namespace std; vector<string> split(const string s, const string delim, const bool keep_empty = true) { vector<string> result; if (delim.empty()) { result.push_back(s); return result; } string::const_iterator substart = s.begin(), subend; while (true) { subend = search(substart, s.end(), delim.begin(), delim.end()); string temp(substart, subend); if (keep_empty || !temp.empty()) { result.push_back(temp); } if (subend == s.end()) { break; } substart = subend + delim.size(); } return result; } int main() { const vector<string> words = split("So close no matter how far", " "); copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n")); } 

Žinoma, „Boost“ split() , kuris veikia iš dalies taip. Ir jei baltos spalvos erdvėje iš tiesų reiškia bet kokio tipo baltą erdvę, naudojant „Boost“ skaidinį su is_any_of() veikia gerai.

65
25 окт. atsakymas duotas Shadow2531 25 okt. 2008-10-25 13:01 '08, 01: 01 pm 2008-10-25 13:01

STL nebeturi tokio metodo.

Tačiau galite naudoti „C strtok() naudodami std::string::c_str() , arba galite rašyti savo. Čia pateikiamas kodo, kurį radau po greito „Google“ paieškos, pavyzdys ( „STL eilutės skaidymas“ ):

 void Tokenize(const string str, vector<string> tokens, const string delimiters = " ") { // Skip delimiters at beginning. string::size_type lastPos = str.find_first_not_of(delimiters, 0); // Find first "non-delimiter". string::size_type pos = str.find_first_of(delimiters, lastPos); while (string::npos != pos || string::npos != lastPos) { // Found a token, add it to the vector. tokens.push_back(str.substr(lastPos, pos - lastPos)); // Skip delimiters. Note the "not_of" lastPos = str.find_first_not_of(delimiters, pos); // Find next "non-delimiter" pos = str.find_first_of(delimiters, lastPos); } } 

Paimta iš: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programavimas-HOWTO-7.html

Jei turite klausimų apie mėginio kodą, palikite komentarą ir paaiškinsiu.

Ir tik todėl, kad jis neįgyvendina typedef vadinamo iteratoriumi arba perkrovimu, << operatorius nereiškia, kad tai yra blogas kodas. Aš dažnai naudoju C funkcijas. Pavyzdžiui, printf ir scanf yra greitesni nei std::cin ir std::cout (žymiai), fopen sintaksė yra daug draugiškesnė dvejetainiams tipams, ir jie taip pat linkę sukurti mažesnius EXEs.

Neparduokite „Elegance over performance“ sandorio.

50
25 окт. atsakymas pateikiamas 25 d. 2008-10-25 12:08 '08, 12:08 2008-10-25 12:08

Čia yra atskyrimo funkcija, kuri:

  • yra dažnas
  • naudoja standartinį C ++ (be priedų)
  • priima kelis ribotuvus
  • ignoruoja tuščius žetonus (juos galima lengvai pakeisti)

     template<typename T> vector<T> split(const T  str, const T  delimiters) { vector<T> v; typename T::size_type start = 0; auto pos = str.find_first_of(delimiters, start); while(pos != T::npos) { if(pos != start) // ignore empty tokens v.emplace_back(str, start, pos - start); start = pos + 1; pos = str.find_first_of(delimiters, start); } if(start < str.length()) // ignore trailing delimiter v.emplace_back(str, start, str.length() - start); // add what left of the string return v; } 

Naudojimo pavyzdys:

  vector<string> v = split<string>("Hello, there; World", ";,"); vector<wstring> v = split<wstring>(L"Hello, there; World", L";,"); 
39
13 марта '12 в 3:09 2012-03-13 03:09 atsakymą pateikė Marco M. kovo 13 d., 12 d., 03:09 2012-03-13 03:09

Kitas lankstus ir greitas būdas

 template<typename Operator> void tokenize(Operator op, const char* input, const char* delimiters) { const char* s = input; const char* e = s; while (*e != 0) { e = s; while (*e != 0  strchr(delimiters, *e) == 0) ++e; if (e - s > 0) { op(s, e - s); } s = e + 1; } } 

Naudokite jį su styginių vektoriumi (Redaguoti: Kadangi kažkas nurodė, kad jis neperima STL klasių ... hrmf;)):

 template<class ContainerType> class Appender { public: Appender(ContainerType container) : container_(container) {;} void operator() (const char* s, unsigned length) { container_.push_back(std::string(s,length)); } private: ContainerType container_; }; std::vector<std::string> strVector; Appender v(strVector); tokenize(v, "A number of words to be tokenized", " \t"); 

Kas tai yra! Ir tai tik vienas būdas naudoti tokenizatorių, pavyzdžiui, kaip paprasčiausiai suskaičiuoti žodžius:

 class WordCounter { public: WordCounter() : noOfWords(0) {} void operator() (const char*, unsigned) { ++noOfWords; } unsigned noOfWords; }; WordCounter wc; tokenize(wc, "A number of words to be counted", " \t"); ASSERT( wc.noOfWords == 7 ); 

Apribota vaizduotės;)

34
01 апр. atsakymas duotas Robert 01 balandžio. 2010-04-01 17:16 '10, 17:16, 2010-04-01 17:16

Turiu dviejų eilučių sprendimą šiai problemai:

 char sep = ' '; std::string s="1 This is an example"; for(size_t p=0, q=0; p!=s.npos; p=q) std::cout << s.substr(p+(p!=0), (q=s.find(sep, p+1))-p-(p!=0)) << std::endl; 

Tada vietoj spausdinimo galite įdėti jį į vektorių.

34
16 сент. Atsakymą pateikė rhomu Sep 16 2012-09-16 17:06 '12 - 17:06 2012-09-16 17:06

Čia yra paprastas sprendimas, kuris naudoja tik standartinę reguliariąją išraišką.

 #include <regex> #include <string> #include <vector> std::vector<string> Tokenize( const string str, const std::regex regex ) { using namespace std; std::vector<string> result; sregex_token_iterator it( str.begin(), str.end(), regex, -1 ); sregex_token_iterator reg_end; for ( ; it != reg_end; ++it ) { if ( !it->str().empty() ) //token could be empty:check result.emplace_back( it->str() ); } return result; } 

Regex argumentas leidžia patikrinti kelis argumentus (tarpai, kableliai ir tt)

Paprastai aš suskirstau tik į tarpus ir kablelius, todėl taip pat turiu šią numatytąją funkciją:

 std::vector<string> TokenizeDefault( const string str ) { using namespace std; regex re( "[\\s,]+" ); return Tokenize( str, re ); } 

"[\\s,]+" tikrina, ar nėra tarpų (kabučių) ir kablelių ( , ).

Atkreipkite dėmesį, kad jei norite, kad vietoj string būtų padalyta „ wstring ,

  • pakeisti visus std::regex į std::wregex
  • pakeisti visus sregex_token_iterator į wsregex_token_iterator

Atkreipkite dėmesį, kad, priklausomai nuo kompiliatoriaus, galite naudoti eilutės argumentą pagal nuorodą.

30
06 мая '14 в 8:49 2014-05-06 08:49 atsakymas pateikiamas dk123 06 gegužės 14 d. 8:49 2014-05-06 08:49

Jei norite naudoti padidinimą, bet norite naudoti visą eilutę kaip ribotuvą (vietoj atskirų simbolių, kaip ir daugelyje anksčiau siūlomų sprendimų), galite naudoti boost_split_iterator .

Kodo, kuriame yra patogus šablonas, pavyzdys:

 #include <iostream> #include <vector> #include <boost/algorithm/string.hpp> template<typename _OutputIterator> inline void split( const std::string str, const std::string delim, _OutputIterator result) { using namespace boost::algorithm; typedef split_iterator<std::string::const_iterator> It; for(It iter=make_split_iterator(str, first_finder(delim, is_equal())); iter!=It(); ++iter) { *(result++) = boost::copy_range<std::string>(*iter); } } int main(int argc, char* argv[]) { using namespace std; vector<string> splitted; split("HelloFOOworldFOO!", "FOO", back_inserter(splitted)); // or directly to console, for example split("HelloFOOworldFOO!", "FOO", ostream_iterator<string>(cout, "\n")); return 0; } 
24
24 марта '11 в 15:47 2011-03-24 15:47 atsakymas pateikiamas zermui kovo 24 d., „11, 15:47, 2011-03-24 15:47

Naudokite std::stringstream , kai dirbate puikiai, ir atlikite būtent tai, ko norite. Jei tik ieškote kito būdo kažkam daryti, galite naudoti std::find() / std::find_first_of() ir std::string::substr() .

Štai pavyzdys:

 #include <iostream> #include <string> int main() { std::string s("Somewhere down the road"); std::string::size_type prev_pos = 0, pos = 0; while( (pos = s.find(' ', pos)) != std::string::npos ) { std::string substring( s.substr(prev_pos, pos-prev_pos) ); std::cout << substring << '\n'; prev_pos = ++pos; } std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word std::cout << substring << '\n'; return 0; } 
23
25 окт. Atsakymą KTC pateikė spalio 25 d. 2008-10-25 12:28 '08, 12:28, 2008-10-25 12:28

Yra funkcija strtok .

 #include<string> using namespace std; vector<string> split(char* str,const char* delim) { char* saveptr; char* token = strtok_r(str,delim, vector<string> result; while(token != NULL) { result.push_back(token); token = strtok_r(NULL,delim, } return result; } 
18
14 июня '10 в 15:17 2010-06-14 15:17 atsakymą pateikė Pratik Deoghare, birželio 14 d., 10 d., 15:17, 2010-06-14 15:17

Čia yra reguliarios išraiškos sprendimas, kuris naudoja tik standartinę reguliariąją išraišką. (Aš esu šiek tiek rūdytas, todėl gali būti keletas sintaksės klaidų, tačiau tai bent jau bendroji idėja)

 #include <regex.h> #include <string.h> #include <vector.h> using namespace std; vector<string> split(string s){ regex r ("\\w+"); //regex matches whole words, (greedy, so no fragment words) regex_iterator<string::iterator> rit ( s.begin(), s.end(), r ); regex_iterator<string::iterator> rend; //iterators to iterate thru words vector<string> result<regex_iterator>(rit, rend); return result; //iterates through the matches to fill the vector } 
17
29 окт. atsakymą pateikė AJMansfield 2012-10-29 19:15 '12, 19:15, 2012-10-29 19:15

Styginių srautas gali būti patogus, jei reikia analizuoti eilutę naudojant ne erdvinius simbolius:

 string s = "Name:JAck; Spouse:Susan; ..."; string dummy, name, spouse; istringstream iss(s); getline(iss, dummy, ':'); getline(iss, name, ';'); getline(iss, dummy, ':'); getline(iss, spouse, ';') 
16
12 авг. atsakymas, kurį pateikė lukmac 12 rug . 2011-08-12 22:05 '11, 10:05 val. 2011-08-12 22:05

Iki šiol naudoju tą, kuris buvo Boostas , bet man reikėjo kažko, kas nepriklauso nuo jo, todėl atėjau į tai

 static void Split(std::vector<std::string> lst, const std::string input, const std::string separators, bool remove_empty = true) { std::ostringstream word; for (size_t n = 0; n < input.size(); ++n) { if (std::string::npos == separators.find(input[n])) word << input[n]; else { if (!word.str().empty() || !remove_empty) lst.push_back(word.str()); word.str(""); } } if (!word.str().empty() || !remove_empty) lst.push_back(word.str()); } 

Gerai, kad separators galite perduoti daugiau nei vieną simbolį.

14
14 янв. atsakymas duotas Goran 14 jan. 2011-01-14 12:22 '11, 12:22, 2011-01-14 12:22

Trumpas ir elegantiškas

 #include <vector> #include <string> using namespace std; vector<string> split(string data, string token) { vector<string> output; size_t pos = string::npos; // size_t to avoid improbable overflow do { pos = data.find(token); output.push_back(data.substr(0, pos)); if (string::npos != pos) data = data.substr(pos + token.size()); } while (string::npos != pos); return output; } 

gali naudoti bet kokią eilutę kaip ribotuvą, taip pat galima naudoti su dvejetainiais duomenimis (std :: string palaiko dvejetainius duomenis, įskaitant nulius)

naudojant:

 auto a = split("this!!is!!!example!string", "!!"); 

išeiti:

 this is !example!string 
14
02 нояб. atsakymą pateikė user1438233 02 Nov. 2015-11-02 17:39 '15, 17:39 pm 2015-11-02 17:39

Naudodamas „strtok“, aš nuvažiavau savo rankas ir naudojosi paskatomis atskirti stygas. Geriausias rastas būdas yra C ++ String Toolkit biblioteka . Tai yra neįtikėtinai lanksti ir greita.

 #include <iostream> #include <vector> #include <string> #include <strtk.hpp> const char *whitespace = " \t\r\n\f"; const char *whitespace_and_punctuation = " \t\r\n\f;,="; int main() { { // normal parsing of a string into a vector of strings std::string s("Somewhere down the road"); std::vector<std::string> result; if( strtk::parse( s, whitespace, result ) ) { for(size_t i = 0; i < result.size(); ++i ) std::cout << result[i] << std::endl; } } { // parsing a string into a vector of floats with other separators // besides spaces std::string s("3.0, 3.14; 4.0"); std::vector<float> values; if( strtk::parse( s, whitespace_and_punctuation, values ) ) { for(size_t i = 0; i < values.size(); ++i ) std::cout << values[i] << std::endl; } } { // parsing a string into specific variables std::string s("angle = 45; radius = 9.9"); std::string w1, w2; float v1, v2; if( strtk::parse( s, whitespace_and_punctuation, w1, v1, w2, v2) ) { std::cout << "word " << w1 << ", value " << v1 << std::endl; std::cout << "word " << w2 << ", value " << v2 << std::endl; } } return 0; } 

Įrankių rinkinys turi daug daugiau lankstumo, nei rodo šis paprastas pavyzdys, tačiau jo naudingumas analizuojant eilutę į naudingus elementus yra neįtikėtinas.

13
07 янв. atsakymas duotas DannyK 07 jan. 2014-01-07 23:28 '14 ne 23:28 2014-01-07 23:28

Aš tai padariau, nes man reikėjo paprasto būdo atskirti linijas nuo c linijų. Be to, jis nesiremia žetonais, o laukus galite naudoti kaip ribotuvus, kurie yra dar vienas reikalingas raktas.

Esu įsitikinęs, kad yra patobulinimų, kuriuos galima patobulinti, kad dar labiau pagerintumėte jo eleganciją ir, be abejo, visas priemones

StringSplitter.hpp:

 #include <vector> #include <iostream> #include <string.h> using namespace std; class StringSplit { private: void copy_fragment(char*, char*, char*); void copy_fragment(char*, char*, char); bool match_fragment(char*, char*, int); int untilnextdelim(char*, char); int untilnextdelim(char*, char*); void assimilate(char*, char); void assimilate(char*, char*); bool string_contains(char*, char*); long calc_string_size(char*); void copy_string(char*, char*); public: vector<char*> split_cstr(char); vector<char*> split_cstr(char*); vector<string> split_string(char); vector<string> split_string(char*); char* String; bool do_string; bool keep_empty; vector<char*> Container; vector<string> ContainerS; StringSplit(char * in) { String = in; } StringSplit(string in) { size_t len = calc_string_size((char*)in.c_str()); String = new char[len + 1]; memset(String, 0, len + 1); copy_string(String, (char*)in.c_str()); do_string = true; } ~StringSplit() { for (int i = 0; i < Container.size(); i++) { if (Container[i] != NULL) { delete[] Container[i]; } } if (do_string) { delete[] String; } } }; 

StringSplitter.cpp:

 #include <string.h> #include <iostream> #include <vector> #include "StringSplit.hpp" using namespace std; void StringSplit::assimilate(char*src, char delim) { int until = untilnextdelim(src, delim); if (until > 0) { char * temp = new char[until + 1]; memset(temp, 0, until + 1); copy_fragment(temp, src, delim); if (keep_empty || *temp != 0) { if (!do_string) { Container.push_back(temp); } else { string x = temp; ContainerS.push_back(x); } } else { delete[] temp; } } } void StringSplit::assimilate(char*src, char* delim) { int until = untilnextdelim(src, delim); if (until > 0) { char * temp = new char[until + 1]; memset(temp, 0, until + 1); copy_fragment(temp, src, delim); if (keep_empty || *temp != 0) { if (!do_string) { Container.push_back(temp); } else { string x = temp; ContainerS.push_back(x); } } else { delete[] temp; } } } long StringSplit::calc_string_size(char* _in) { long i = 0; while (*_in++) { i++; } return i; } bool StringSplit::string_contains(char* haystack, char* needle) { size_t len = calc_string_size(needle); size_t lenh = calc_string_size(haystack); while (lenh--) { if (match_fragment(haystack + lenh, needle, len)) { return true; } } return false; } bool StringSplit::match_fragment(char* _src, char* cmp, int len) { while (len--) { if (*(_src + len) != *(cmp + len)) { return false; } } return true; } int StringSplit::untilnextdelim(char* _in, char delim) { size_t len = calc_string_size(_in); if (*_in == delim) { _in += 1; return len - 1; } int c = 0; while (*(_in + c) != delim  c < len) { c++; } return c; } int StringSplit::untilnextdelim(char* _in, char* delim) { int s = calc_string_size(delim); int c = 1 + s; if (!string_contains(_in, delim)) { return calc_string_size(_in); } else if (match_fragment(_in, delim, s)) { _in += s; return calc_string_size(_in); } while (!match_fragment(_in + c, delim, s)) { c++; } return c; } void StringSplit::copy_fragment(char* dest, char* src, char delim) { if (*src == delim) { src++; } int c = 0; while (*(src + c) != delim  *(src + c)) { *(dest + c) = *(src + c); c++; } *(dest + c) = 0; } void StringSplit::copy_string(char* dest, char* src) { int i = 0; while (*(src + i)) { *(dest + i) = *(src + i); i++; } } void StringSplit::copy_fragment(char* dest, char* src, char* delim) { size_t len = calc_string_size(delim); size_t lens = calc_string_size(src); if (match_fragment(src, delim, len)) { src += len; lens -= len; } int c = 0; while (!match_fragment(src + c, delim, len)  (c < lens)) { *(dest + c) = *(src + c); c++; } *(dest + c) = 0; } vector<char*> StringSplit::split_cstr(char Delimiter) { int i = 0; while (*String) { if (*String != Delimiter  i == 0) { assimilate(String, Delimiter); } if (*String == Delimiter) { assimilate(String, Delimiter); } i++; String++; } String -= i; delete[] String; return Container; } vector<string> StringSplit::split_string(char Delimiter) { do_string = true; int i = 0; while (*String) { if (*String != Delimiter  i == 0) { assimilate(String, Delimiter); } if (*String == Delimiter) { assimilate(String, Delimiter); } i++; String++; } String -= i; delete[] String; return ContainerS; } vector<char*> StringSplit::split_cstr(char* Delimiter) { int i = 0; size_t LenDelim = calc_string_size(Delimiter); while(*String) { if (!match_fragment(String, Delimiter, LenDelim)  i == 0) { assimilate(String, Delimiter); } if (match_fragment(String, Delimiter, LenDelim)) { assimilate(String,Delimiter); } i++; String++; } String -= i; delete[] String; return Container; } vector<string> StringSplit::split_string(char* Delimiter) { do_string = true; int i = 0; size_t LenDelim = calc_string_size(Delimiter); while (*String) { if (!match_fragment(String, Delimiter, LenDelim)  i == 0) { assimilate(String, Delimiter); } if (match_fragment(String, Delimiter, LenDelim)) { assimilate(String, Delimiter); } i++; String++; } String -= i; delete[] String; return ContainerS; } 

Pavyzdžiai:

 int main(int argc, char*argv[]) { StringSplit ss = "This:CUT:is:CUT:an:CUT:example:CUT:cstring"; vector<char*> Split = ss.split_cstr(":CUT:"); for (int i = 0; i < Split.size(); i++) { cout << Split[i] << endl; } return 0; } 

Bus rodoma:

Tai yra
tai yra

pavyzdys
CString

 int main(int argc, char*argv[]) { StringSplit ss = "This:is:an:example:cstring"; vector<char*> Split = ss.split_cstr(':'); for (int i = 0; i < Split.size(); i++) { cout << Split[i] << endl; } return 0; } int main(int argc, char*argv[]) { string mystring = "This[SPLIT]is[SPLIT]an[SPLIT]example[SPLIT]string"; StringSplit ss = mystring; vector<string> Split = ss.split_string("[SPLIT]"); for (int i = 0; i < Split.size(); i++) { cout << Split[i] << endl; } return 0; } int main(int argc, char*argv[]) { string mystring = "This|is|an|example|string"; StringSplit ss = mystring; vector<string> Split = ss.split_string('|'); for (int i = 0; i < Split.size(); i++) { cout << Split[i] << endl; } return 0; } 

Išsaugokite tuščius įrašus (pagal nutylėjimą, tuščias įrašas neįtrauktas):

 StringSplit ss = mystring; ss.keep_empty = true; vector<string> Split = ss.split_string(":DELIM:"); 

Tikslas buvo, kad jis atrodytų kaip C # Split () metodas, kai linijos skaidymas yra toks paprastas kaip:

 String[] Split = "Hey:cut:what's:cut:your:cut:name?".Split(new[]{":cut:"}, StringSplitOptions.None); foreach(String X in Split) { Console.Write(X); }