c++ - मैं स्ट्रिंग के शब्दों पर कैसे पुन: प्रयास करूं?




string split (20)

इसके लायक होने के लिए, इनपुट स्ट्रिंग से टोकन निकालने का एक और तरीका है, केवल मानक लाइब्रेरी सुविधाओं पर निर्भर करता है। यह एसटीएल के डिजाइन के पीछे शक्ति और लालित्य का एक उदाहरण है।

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

निकाले गए टोकन को आउटपुट स्ट्रीम में कॉपी करने के बजाय, एक ही जेनेरिक copy एल्गोरिदम का उपयोग करके, उन्हें एक कंटेनर में डाल सकता है।

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

... या सीधे vector बनाओ:

vector<string> tokens{istream_iterator<string>{iss},
                      istream_iterator<string>{}};

मैं एक स्ट्रिंग के शब्दों पर फिर से प्रयास करने की कोशिश कर रहा हूँ।

स्ट्रिंग को व्हाइटस्पेस से अलग शब्दों से बना माना जा सकता है।

ध्यान दें कि मुझे सी स्ट्रिंग फ़ंक्शंस या उस तरह के चरित्र मैनिपुलेशन / एक्सेस में रूचि नहीं है। इसके अलावा, कृपया अपने उत्तर में दक्षता पर लालित्य के लिए प्राथमिकता दें।

मेरे पास अभी सबसे अच्छा समाधान है:

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

क्या ऐसा करने के लिए एक और शानदार तरीका है?


एक रेगेक्स समाधान है जो केवल मानक रेगेक्स लाइब्रेरी का उपयोग करता है। (मैं थोड़ा जंगली हूँ, इसलिए कुछ वाक्यविन्यास त्रुटियां हो सकती हैं, लेकिन यह कम से कम सामान्य विचार है)

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

जिनके साथ यह कोड आकार के लिए सभी दक्षता बलिदान के लिए अच्छी तरह से बैठता नहीं है और लालित्य के प्रकार के रूप में "कुशल" को देखते हैं, तो निम्नलिखित को एक मीठा स्थान मारा जाना चाहिए (और मुझे लगता है कि टेम्पलेट कंटेनर क्लास एक असाधारण सुरुचिपूर्ण जोड़ है।):

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

मैं आमतौर पर std::vector<std::string> प्रकारों का उपयोग अपने दूसरे पैरामीटर ( ContainerT ) के रूप में करना चुनता हूं ... लेकिन list<> vector<> तुलना में तेज़ तरीका है vector<> जब प्रत्यक्ष पहुंच की आवश्यकता नहीं होती है, और आप भी बना सकते हैं अपनी खुद की स्ट्रिंग क्लास और std::list<subString> जैसे कुछ का उपयोग करें जहां subString अविश्वसनीय गति बढ़ने के लिए कोई प्रतिलिपि नहीं करता है।

यह इस पृष्ठ पर सबसे तेज टोकननाइजेशन के रूप में तेज़ी से दोगुनी से अधिक है और कुछ अन्य लोगों की तुलना में लगभग 5 गुना तेज है। साथ ही सही पैरामीटर प्रकारों के साथ आप अतिरिक्त गति वृद्धि के लिए सभी स्ट्रिंग और सूची प्रतियों को खत्म कर सकते हैं।

इसके अतिरिक्त यह परिणाम की अत्यधिक (अक्षम अक्षम) वापसी नहीं करता है, बल्कि यह टोकन को एक संदर्भ के रूप में पास करता है, इस प्रकार यदि आप चाहें तो एकाधिक कॉल का उपयोग करके टोकन बनाने की अनुमति भी देते हैं।

आखिरकार यह आपको यह निर्दिष्ट करने की अनुमति देता है कि अंतिम वैकल्पिक पैरामीटर के माध्यम से परिणामों से खाली टोकन को ट्रिम करना है या नहीं।

इसकी सभी जरूरत है std::string ... बाकी वैकल्पिक हैं। यह धाराओं या बूस्ट लाइब्रेरी का उपयोग नहीं करता है, लेकिन स्वाभाविक रूप से इन विदेशी प्रकारों में से कुछ को स्वीकार करने में सक्षम होने के लिए पर्याप्त लचीला है।


फिर भी एक और लचीला और तेज़ तरीका

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

स्ट्रिंग्स के वेक्टर के साथ इसका उपयोग करने के लिए (संपादित करें: चूंकि किसी ने एसटीएल कक्षाओं का वारिस नहीं किया है ... एचआरएमएफ;)):

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

बस! और यह टोकननाइज़र का उपयोग करने का एक ही तरीका है, जैसे कि शब्दों को कैसे गिनना है:

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

कल्पना से सीमित;)


मुझे निम्नलिखित पसंद हैं क्योंकि यह परिणाम को वेक्टर में रखता है, एक स्ट्रिंग को एक डेलीम के रूप में समर्थन देता है और खाली मूल्यों को रखने पर नियंत्रण देता है। लेकिन, यह तब अच्छा नहीं लग रहा है।

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

बेशक, बूस्ट में एक split() जो आंशिक रूप से उस तरह काम करता है। और, यदि 'व्हाइट-स्पेस' से, आप वास्तव में किसी भी प्रकार का श्वेत-स्थान का मतलब रखते हैं, तो बूस्ट के विभाजन के साथ is_any_of() बहुत अच्छा काम करता है।


मेरे पास इस समस्या का 2 लाइन समाधान है:

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;

फिर प्रिंटिंग के बजाय आप इसे एक वेक्टर में डाल सकते हैं।


यदि आप बूस्ट का उपयोग करना चाहते हैं, लेकिन पूरी स्ट्रिंग को डिलीमीटर के रूप में उपयोग करना चाहते हैं (पहले boost_split_iterator समाधानों में से अधिकांश वर्णों के बजाय), तो आप boost_split_iterator उपयोग कर सकते हैं।

सुविधाजनक टेम्पलेट सहित उदाहरण कोड:

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

यदि आपको गैर-स्पेस प्रतीकों द्वारा स्ट्रिंग को पार्स करने की आवश्यकता है तो स्ट्रिंगस्ट्रीम सुविधाजनक हो सकता है:

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

यह स्टैक ओवरफ़्लो प्रश्न के समान है I 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;
    }
}

यहाँ एक और समाधान है। यह कॉम्पैक्ट और उचित रूप से कुशल है:

std::vector<std::string> split(const std::string &text, 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;
}

स्ट्रिंग सेपरेटर्स, वाइड स्ट्रिंग इत्यादि को संभालने के लिए इसे आसानी से टेम्पलेट किया जा सकता है।

ध्यान दें कि "" एक खाली स्ट्रिंग और विभाजन में परिणाम "," (यानी sep) परिणाम दो रिक्त तारों में होते हैं।

खाली टोकन छोड़ने के लिए इसे आसानी से विस्तारित किया जा सकता है:

std::vector<std::string> split(const std::string &text, 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;
}

यदि खाली टोकन छोड़ते समय एकाधिक डिलीमीटर पर एक स्ट्रिंग को विभाजित करना वांछित है, तो इस संस्करण का उपयोग किया जा सकता है:

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

यहां एक सरल समाधान है जो केवल मानक रेगेक्स लाइब्रेरी का उपयोग करता है

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

रेगेक्स तर्क कई तर्कों (रिक्त स्थान, अल्पविराम, आदि) की जांच करने की अनुमति देता है

मैं आमतौर पर रिक्त स्थान और अल्पविरामों पर विभाजित होने की जांच करता हूं, इसलिए मेरे पास यह डिफ़ॉल्ट कार्य भी है:

std::vector<string> TokenizeDefault( const string str )
{
    using namespace std;

    regex re( "[\\s,]+" );

    return Tokenize( str, re );
}

रिक्त स्थान ( \\s ) और अल्पविराम ( , ) के लिए "[\\s,]+" जांचता है।

नोट, यदि आप string बजाय wstring को विभाजित करना चाहते हैं,

  • सभी std::regex को std::wregex
  • सभी sregex_token_iterator को wsregex_token_iterator

नोट, आप अपने कंपाइलर के आधार पर संदर्भ द्वारा स्ट्रिंग तर्क भी लेना चाहेंगे।


strtok नामक एक समारोह है।

#include<string>
using namespace std;

vector<string> split(char* str,const char* delim)
{
    char* saveptr;
    char* token = strtok_r(str,delim,&saveptr);

    vector<string> result;

    while(token != NULL)
    {
        result.push_back(token);
        token = strtok_r(NULL,delim,&saveptr);
    }
    return result;
}

इस बारे में क्या:

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

इसे करने का एक और तरीका यहाँ है ..

void split_string(string text,vector<string>& words)
{
  int i=0;
  char ch;
  string word;

  while(ch=text[i++])
  {
    if (isspace(ch))
    {
      if (!word.empty())
      {
        words.push_back(word);
      }
      word = "";
    }
    else
    {
      word += ch;
    }
  }
  if (!word.empty())
  {
    words.push_back(word);
  }
}

मैं इस कार्य के लिए बूस्ट / रेगेक्स विधियों का उपयोग करना चाहता हूं क्योंकि वे विभाजन मानदंडों को निर्दिष्ट करने के लिए अधिकतम लचीलापन प्रदान करते हैं।

#include <iostream>
#include <string>
#include <boost/regex.hpp>

int main() {
    std::string line("A:::line::to:split");
    const boost::regex re(":+"); // one or more colons

    // -1 means find inverse matches aka split
    boost::sregex_token_iterator tokens(line.begin(),line.end(),re,-1);
    boost::sregex_token_iterator end;

    for (; tokens != end; ++tokens)
        std::cout << *tokens << std::endl;
}

Boost जाओ ! : -)

#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string.hpp>
#include <iostream>
#include <vector>

using namespace std;
using namespace boost;

int main(int argc, char**argv) {
    typedef vector < string > list_type;

    list_type list;
    string line;

    line = "Somewhere down the road";
    split(list, line, is_any_of(" "));

    for(int i = 0; i < list.size(); i++)
    {
        cout << list[i] << endl;
    }

    return 0;
}

यह उदाहरण आउटपुट देता है -

Somewhere
down
the
road

नीचे दिया गया कोड strtok()स्ट्रिंग को टोकन में विभाजित करने और वेक्टर में टोकन स्टोर करने के लिए उपयोग करता है।

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>

using namespace std;


char one_line_string[] = "hello hi how are you nice weather we are having ok then bye";
char seps[]   = " ,\t\n";
char *token;



int main()
{
   vector<string> vec_String_Lines;
   token = strtok( one_line_string, seps );

   cout << "Extracting and storing data in a vector..\n\n\n";

   while( token != NULL )
   {
      vec_String_Lines.push_back(token);
      token = strtok( NULL, seps );
   }
     cout << "Displaying end result in vector line storage..\n\n";

    for ( int i = 0; i < vec_String_Lines.size(); ++i)
    cout << vec_String_Lines[i] << "\n";
    cout << "\n\n\n";


return 0;
}

मैंने इसे इसलिए बनाया क्योंकि मुझे तारों और सी-आधारित तारों को विभाजित करने का एक आसान तरीका चाहिए ... उम्मीद है कि कोई और इसे भी उपयोगी पा सकता है। इसके अलावा यह टोकन पर भरोसा नहीं करता है और आप फ़ील्ड का उपयोग डिलीमीटर के रूप में कर सकते हैं, जो कि मुझे एक और कुंजी चाहिए।

मुझे यकीन है कि ऐसे सुधार हैं जो इसके लालित्य को और भी बेहतर बनाने के लिए किए जा सकते हैं और कृपया हर तरह से करें

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

उदाहरण:

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

आउटपुट होगा:

यह
है
एक
उदाहरण
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;
}

खाली प्रविष्टियों को रखने के लिए (डिफ़ॉल्ट खालीियों को छोड़ दिया जाएगा):

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

लक्ष्य इसे सी # की स्प्लिट () विधि के समान बनाना था जहां एक स्ट्रिंग को विभाजित करना उतना आसान है जितना:

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

foreach(String X in Split)
{
    Console.Write(X);
}

मुझे आशा है कि कोई और इसे उतना उपयोगी लगेगा जितना मैं करता हूं।


यह उत्तर स्ट्रिंग लेता है और इसे तारों के वेक्टर में रखता है। यह बूस्ट लाइब्रेरी का उपयोग करता है।

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

हाल ही में मुझे ऊंट-शब्द वाले शब्द को उपशब्दों में विभाजित करना पड़ा। कोई delimiters, सिर्फ ऊपरी अक्षर हैं।

#include <string>
#include <list>
#include <locale> // std::isupper

template<class String>
const std::list<String> split_camel_case_string(const String &s)
{
    std::list<String> R;
    String w;

    for (String::const_iterator i = s.begin(); i < s.end(); ++i) {  {
        if (std::isupper(*i)) {
            if (w.length()) {
                R.push_back(w);
                w.clear();
            }
        }
        w += *i;
    }

    if (w.length())
        R.push_back(w);
    return R;
}

उदाहरण के लिए, यह "AQueryTrades" को "ए", "क्वेरी" और "ट्रेड" में विभाजित करता है। समारोह संकीर्ण और चौड़े तारों के साथ काम करता है। क्योंकि यह वर्तमान लोकेल का सम्मान करता है क्योंकि यह "RaumfahrtÜberwachungsVerordnung" को "Raumfahrt", "Überwachungs" और "Verordnung" में विभाजित करता है।

नोट std::upperवास्तव में फ़ंक्शन टेम्पलेट तर्क के रूप में पारित किया जाना चाहिए। फिर इस समारोह से अधिक सामान्यीकृत ",", जैसे , ";"या " "भी delimiters पर विभाजित कर सकते हैं।





split