Kako prelazim kroz riječi?

Pokušavam razvrstati riječi niza.

Može se pretpostaviti da se niz sastoji od riječi razdvojenih razmacima.

Imajte na umu da me ne zanimaju funkcije niza C ili slične manipulacije / pristup znakovima. Osim toga, molimo dajte prednost eleganciji u odnosu na učinkovitost vašeg odgovora.

Najbolje rješenje koje sada imam je:

 #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); } 

Postoji li još elegantniji način za to?

2749
25 окт. postavio Ashwin Nanjappa 25. listopada 2008-10-25 11:58 '08 u 11:58 2008-10-25 11:58
@ 76 odgovora
  • 1
  • 2
  • 3

Za koliko to košta, ovdje je još jedan način za izdvajanje tokena iz ulaznog niza, oslanjajući se samo na standardne knjižnice. Ovo je primjer snage i elegancije STL dizajna.

 #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")); } 

Umjesto kopiranja dohvaćenih tokena u izlazni tok, možete ih umetnuti u spremnik koristeći isti opći algoritam copy .

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

... ili izravno izradite vector :

 vector<string> tokens{istream_iterator<string>{iss}, istream_iterator<string>{}}; 
1241
26 окт. Odgovor dao Zunino 26. listopada 2008-10-26 03:43 '08 u 3:43 2008-10-26 03:43

Koristim ovo kako bih odvojio niz razdjelnikom. Prvi stavlja rezultate u unaprijed konstruirani vektor, drugi vraća novi vektor.

 std::vector<std::string> x = split("one:two::three", ':'); 
2343
25 окт. odgovor je dao Evan Teran 25. listopada. 2008-10-25 21:21 '08 u 21:21 2008-10-25 21:21

Moguće rješenje pomoću značajke Boost može biti:

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

Ovaj pristup može biti čak i brži od pristupa stringstream . Budući da se radi o univerzalnoj funkciji predloška, ​​ona se može koristiti za razdvajanje drugih vrsta žica (wchar, itd. Ili UTF-8) pomoću svih vrsta razdjelnika.

Za detalje pogledajte.

810
25 окт. odgovor je dat ididak 25 listopada. 2008-10-25 23:28 '08 u 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 odgovor je dat kev 6. ožujka '11 u 8:52 2011-03-06 08:52

Za one s kojima nije prikladno žrtvovati svu učinkovitost za veličinu koda i vidjeti "djelotvornu" kao vrstu elegancije, sljedeći bi trebao imati slatku točku (i mislim da je kontejnerski predložak iznenađujuće elegantan dodatak.):

 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; } } 

Obično radije koristim std::vector<std::string> kao svoj drugi parametar ( ContainerT ) ... ali list<> brži od vector<> kada izravan pristup nije potreban, a možete čak i napraviti vlastiti niz i koristite nešto poput std::list<subString> , gdje subString ne pravi kopije za nevjerojatnu brzinu.

To je više nego dvostruko brže od najbrže označene na ovoj stranici i gotovo 5 puta brže od nekih drugih. Također, s idealnim vrstama parametara, možete ukloniti sve kopije nizova i popisa za dodatno povećanje brzine.

Osim toga, ne izvodi (vrlo neučinkovit) rezultat, već prolazi tokene kao referencu, što vam također omogućuje stvaranje tokena pomoću nekoliko poziva ako želite.

Konačno, omogućuje vam da navedete želite li isprazniti prazne oznake iz rezultata pomoću zadnjeg neobaveznog parametra.

Sve što mu treba je std::string ... ostalo je opcionalno. Ne koristi niti niti biblioteku s poticajima, ali je dovoljno fleksibilna da prirodno prihvati neke od tih stranih tipova.

174
29 сент. Odgovor daje Marius 29. rujna. 2009-09-29 18:12 '09 u 18:12 2009-09-29 18:12

Evo još jednog rješenja. Kompaktan je i učinkovit:

 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; } 

Može se jednostavno planirati za rukovanje razdjelnicima redaka, širokim nizovima itd.

Primijetite da podjela "" daje jedan prazan red, a dijeljenje "," (tj. Odustajanje) rezultira s dva prazna retka.

Također se može lako postaviti na preskakanje praznih oznaka:

 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; } 

Ako je za preskakanje praznih tokena potrebna podjela linije na nekoliko razdjelnika, ova se verzija može koristiti:

 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 сент. Odgovor koji je dao Alec Thomas 13. rujna 2011-09-13 23:46 '11 u 11:46 2011-09-13 23:46

Ovo je moj omiljeni način ponavljanja niza. Za svaku riječ možete učiniti što god želite.

 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 окт. odgovor je dao gnomed 25. listopada 2008-10-25 12:16 '08 u 12:16 2008-10-25 12:16

To je kao pitanje preljeva stog.Kako želim tokenizirati niz u 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 окт. odgovor je dat Ferruccio 25. listopada. 2008-10-25 13:58 '08 u 13:58 2008-10-25 13:58

Sviđa mi se sljedeće jer rezultate stavlja u vektor, podržava string kao separator i daje kontrolu nad očuvanjem null vrijednosti. Ali ne izgleda tako dobro.

 #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")); } 

Naravno, Boost ima split() , što djeluje djelomično ovako. I, ako po bijelom prostoru stvarno podrazumijevate bilo koju vrstu is_any_of() prostora, upotreba Boost particije s is_any_of() radi dobro.

65
25 окт. odgovor je dat Shadow2531 25. listopada. 2008-10-25 13:01 '08 u 13:01 2008-10-25 13:01

STL više nema takvu metodu.

Međutim, možete koristiti funkciju C strtok() koristeći std::string::c_str() , ili možete napisati vlastitu. Evo primjera koda koji sam pronašao nakon brzog Google pretraživanja ( "Razdvajanje STL niza" ):

 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); } } 

Preuzeto s: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html

Ako imate pitanja o primjeru koda, ostavite komentar i ja ću vam objasniti.

I samo zato što ne implementira typedef zove iterator ili preopterećenje, << operator ne znači da je to loš kôd. Često koristim funkcije C. Na primjer, printf i scanf su brži od std::cin i std::cout (značajno), fopen sintaksa je mnogo ugodnija za binarne tipove, a također imaju tendenciju stvaranja manjih EXE-ova.

Nemojte prodavati ovaj posao "Elegance over performance" .

50
25 окт. odgovor je dan nlaq 25 oct. 2008-10-25 12:08 '08 u 12:08 2008-10-25 12:08

Ovdje je funkcija razdvajanja koja:

  • je uobičajeno
  • koristi standardni C ++ (bez poboljšanja)
  • prihvaća više razdjelnika
  • zanemaruje prazne tokene (mogu se lako promijeniti)

     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; } 

Primjer uporabe:

  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 odgovor je dao Marco M. 13. ožujka '12 u 3:09 2012-03-13 03:09

Još jedan fleksibilan i brz način

 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; } } 

Koristite ga s nizom vektora (Uredi: jer je netko naveo da ne nasljeđuje STL klase ... 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"); 

Što je ovo? A to je samo jedan način da se koristi tokenizer, na primjer, kako jednostavno brojati riječi:

 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 ); 

Ograničeno maštom;)

34
01 апр. odgovor je dat Robert 01 apr. 2010-04-01 17:16 '10 u 17:16 2010-04-01 17:16

Imam rješenje od 2 retka za ovaj problem:

 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 umjesto ispisa možete ga staviti u vektor.

34
16 сент. Odgovor daje rhomu 16. rujna 2012-09-16 17:06 '12 u 17:06 2012-09-16 17:06

Ovdje je jednostavno rješenje koje koristi samo standardnu ​​biblioteku regularnih izraza.

 #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; } 

Argument regex omogućuje provjeru više argumenata (razmaci, zarezi, itd.)

Obično provjeravam cijepanje samo u razmake i zareze, tako da imam i tu zadanu funkciju:

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

"[\\s,]+" provjerava razmake ( \\s ) i zareze ( , ).

Imajte na umu da ako želite podijeliti wstring umjesto string ,

  • promijeniti sve std::regex u std::wregex
  • promijeni sve sregex_token_iterator na wsregex_token_iterator

Imajte na umu da također možete uzeti string argument po referenci, ovisno o vašem prevodiocu.

30
06 мая '14 в 8:49 2014-05-06 08:49 odgovor je dk123 6. svibnja '14 u 8:49 2014-05-06 08:49

Ako želite koristiti boost, ali želite koristiti cijeli niz kao graničnik (umjesto pojedinačnih znakova, kao u većini prethodno predloženih rješenja), možete koristiti boost_split_iterator .

Primjer koda koji uključuje prikladan predložak:

 #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 odgovor je dao zerm 24. ožujka '11 u 15:47 2011-03-24 15:47

Koristite std::stringstream dok radite sjajno i radite točno ono što želite. Ako samo tražite drugi način da učinite nešto, možete koristiti std::find() / std::find_first_of() i std::string::substr() .

Evo primjera:

 #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 окт. Odgovor daje KTC 25. listopada. 2008-10-25 12:28 '08 u 12:28 2008-10-25 12:28

Postoji funkcija koja se zove 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 odgovor daje Pratik Deoghare 14. lipnja 2010. u 15:17 2010-06-14 15:17

Ovo je rješenje regularnog izraza koje koristi samo standardnu ​​biblioteku regularnih izraza. (Malo sam zahrđao, tako da može biti nekoliko sintaksnih pogrešaka, ali ovo je barem općenita ideja)

 #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 окт. Odgovor je dao AJMansfield 29. listopada. 2012-10-29 19:15 '12 u 19:15 2012-10-29 19:15

Struja niza može biti prikladna ako trebate analizirati niz pomoću ne-prostornih znakova:

 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 авг. odgovor od lukmac 12 aug. 2011-08-12 22:05 '11 u 22:05 2011-08-12 22:05

Do sada sam koristio onaj koji je bio u Boostu , ali mi je trebalo nešto što ne ovisi o tome, pa sam došao do ovoga

 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()); } 

Dobro je da u separators možete prenijeti više znakova.

14
14 янв. odgovor je dat Goran 14 jan. 2011-01-14 12:22 '11 u 12:22 2011-01-14 12:22

Kratka i elegantna

 #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; } 

može koristiti bilo koji niz kao graničnik, također se može koristiti s binarnim podacima (std :: string podržava binarne podatke, uključujući nule)

putem:

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

izlaz:

 this is !example!string 
14
02 нояб. odgovor daje korisnik1438233 02. studenog. 2015-11-02 17:39 '15 u 17:39 2015-11-02 17:39

Koristio sam vlastitu strtok i koristio pojačanje kako bih razdvojio žice. Najbolji način koji sam pronašao je C ++ String Toolkit Library . Nevjerojatno je fleksibilan i brz.

 #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; } 

Skup alata ima mnogo veću fleksibilnost nego što ovaj jednostavan primjer pokazuje, ali njegova korisnost u analizi niza u korisne elemente je nevjerojatna.

13
07 янв. odgovor je dannyK 07 jan. 2014-01-07 23:28 '14 u 23:28 2014-01-07 23:28

Učinio sam to jer mi je bio potreban jednostavan način da odvojim linije od c linija ... Nadam se da će netko drugi biti koristan. Također, ne oslanja se na žetone, a polja možete koristiti kao razdjelnike, što je još jedan ključ koji trebam.

Siguran sam da postoje poboljšanja koja se mogu poboljšati kako bi se dodatno poboljšala njegova elegancija i, molim, svakako

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; } 

primjeri:

 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; } 

Prikazat će se:

Jeste
ovo je

primjer
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; } 

Spremi prazne unose (prema zadanim se postavkama prazni unosi isključuju):

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

Cilj je bio da izgleda kao metoda C # Split (), gdje je podjela retka jednostavna kao:

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

Nadam se da će to netko drugi smatrati korisnim, poput mene.

11
31 авг. Odgovor je dao Steve Dell 31. kolovoza. 2012-08-31 22:11 '12 u 10:11 pm 2012-08-31 22:11

Kako o ovome:

 #include <string> #include <vector> using namespace std; vector<string> split(string str, const char delim) { vector<string> v; string tmp; for(string::const_iterator i; i = str.begin(); i <= str.end(); ++i) { if(*i != delim  i != str.end()) { tmp += *i; } else { v.push_back(tmp); tmp = ""; } } return v; } 
10
24 июня '11 в 1:04 2011-06-24 01:04 odgovor je dat gibbz 24. lipnja '11 u 1:04 2011-06-24 01:04