c++ - সফটওয - সি ল্যাংগুয়েজ




আমি কিভাবে একটি স্ট্রিং এর শব্দ উপর পুনরাবৃত্তি করবেন? (20)

Heres একটি regex সমাধান যা শুধুমাত্র স্ট্যান্ডার্ড regex লাইব্রেরি ব্যবহার করে। (আমি একটু ক্ষতিকারক, তাই কিছু সিনট্যাক্স ত্রুটি হতে পারে, কিন্তু এটি অন্তত সাধারণ ধারণা)

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

আমি একটি স্ট্রিং এর শব্দ উপর পুনরাবৃত্তি করার চেষ্টা করছি।

স্ট্রিং হোয়াইটস্পেস দ্বারা আলাদা শব্দ গঠিত হতে অনুমিত হতে পারে।

উল্লেখ্য যে আমি সি স্ট্রিং ফাংশন বা চরিত্র ম্যানিপুলেশন / অ্যাক্সেসের যে ধরনের আগ্রহী নই। এছাড়াও, আপনার উত্তর দক্ষতা উপর কমনীয়তা অগ্রাধিকার দিতে দয়া করে।

এখন আমার সবচেয়ে ভাল সমাধান হল:

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

এটা করার জন্য আরো মার্জিত উপায় আছে?


আপনি যদি বুস্ট ব্যবহার করতে চান তবে ডিলিমিটার হিসাবে একটি সম্পূর্ণ স্ট্রিং ব্যবহার করতে চান (পূর্বের প্রস্তাবিত সমাধানগুলি সর্বাধিক হিসাবে একক অক্ষরের পরিবর্তে), আপনি 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;
}

আমি একটি delimiter দ্বারা স্ট্রিং বিভক্ত করার জন্য এই ব্যবহার। প্রথমটি একটি প্রাক-নির্মিত ভেক্টরের ফলাফল রাখে, দ্বিতীয়টি একটি নতুন ভেক্টর প্রদান করে।

#include <string>
#include <sstream>
#include <vector>
#include <iterator>

template<typename Out>
void split(const std::string &s, char delim, Out result) {
    std::stringstream ss(s);
    std::string item;
    while (std::getline(ss, item, delim)) {
        *(result++) = item;
    }
}

std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    split(s, delim, std::back_inserter(elems));
    return elems;
}

উল্লেখ্য যে এই সমাধানটি খালি টোকেনগুলি এড়িয়ে চলে না, তাই নিম্নলিখিত 4 টি আইটেম খুঁজে পাবে, যার মধ্যে একটি খালি:

std::vector<std::string> x = split("one:two::three", ':');

আমি নিম্নলিখিতটিকে পছন্দ করি কারণ এটি একটি ভেক্টরের ফলাফল রাখে, একটি স্ট্রিংকে একটি ডেলিম হিসাবে সমর্থন করে এবং খালি মানগুলি ধরে রাখতে নিয়ন্ত্রণ দেয়। কিন্তু, এটি ভাল হিসাবে তাকান না।

#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() যা আংশিকভাবে এটির মতো কাজ করে। এবং, 'হোয়াইট-স্পেস' দ্বারা, আপনি সত্যিই কোনও হোয়াইট-স্পেস মানে, বুস্টের split ব্যবহার করে is_any_of() দুর্দান্ত কাজ করে।


এখানে অন্য সমাধান। এটি কম্প্যাক্ট এবং যুক্তিসঙ্গতভাবে দক্ষ:

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

এটি সহজেই স্ট্রিং বিভাজক, প্রশস্ত স্ট্রিং ইত্যাদি পরিচালনা করতে templatised করা যেতে পারে।

মনে রাখবেন যে বিভাজন "" একটি একক খালি স্ট্রিং এবং বিভক্ত ফলাফল "," (অর্থাৎ সিপি) দুটি ফাঁকা স্ট্রিংগুলির ফলাফল।

খালি টোকেনগুলি বাদ দেওয়ার জন্য এটি সহজেই প্রসারিত করা যেতে পারে:

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

খালি টোকেন বাদ দেওয়ার সময় একাধিক delimiters একটি স্ট্রিং বিভক্ত করা হয়, এই সংস্করণ ব্যবহার করা যেতে পারে:

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

এখানে একটি বিভক্ত ফাংশন যে:

  • জেনেরিক
  • স্ট্যান্ডার্ড সি ++ ব্যবহার করে (কোন বুস্ট)
  • একাধিক delimiters গ্রহণ
  • খালি টোকেন উপেক্ষা করে (সহজেই পরিবর্তন করা যেতে পারে)

    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's left of the string
        return v;
    }
    

উদাহরণ ব্যবহার:

    vector<string> v = split<string>("Hello, there; World", ";,");
    vector<wstring> v = split<wstring>(L"Hello, there; World", L";,");

এটি একটি স্ট্রিং মাধ্যমে পুনরাবৃত্তি আমার প্রিয় উপায়। আপনি প্রতি শব্দ চান যাই হোক না কেন করতে পারেন।

string line = "a line of text to iterate through";
string word;

istringstream iss(line, istringstream::in);

while( iss >> word )     
{
    // Do something on `word` here...
}

এটি স্ট্যাক ওভারফ্লো প্রশ্নটির অনুরূপ আমি কিভাবে 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;
    }
}

এতদূর আমি Boost একটিকে ব্যবহার করেছি, কিন্তু আমার এমন কিছু দরকার যা তার উপর নির্ভর করে না, তাই আমি এটার কাছে এসেছি:

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

একটি ভাল পয়েন্ট separatorsআপনি একাধিক চরিত্র পাস করতে পারেন।


এসটিএল ইতিমধ্যে যেমন একটি পদ্ধতি উপলব্ধ নেই।

যাইহোক, আপনি std::string::c_str() সদস্য ব্যবহার করে সি এর strtok() ফাংশনটি ব্যবহার করতে পারেন, অথবা আপনি নিজের লিখতে পারেন। এখানে একটি দ্রুত Google অনুসন্ধানের পরে পাওয়া একটি কোড নমুনা ( "STL স্ট্রিং বিভক্ত" ):

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

থেকে নেওয়া হয়েছে: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html

যদি আপনার কোড নমুনা সম্পর্কে প্রশ্ন থাকে তবে একটি মন্তব্য করুন এবং আমি ব্যাখ্যা করব।

এবং এটি কারণ এটি typedef নামে টাইপডফ প্রয়োগ না করে বা << লোড করা << অপারেটরের মানে এটি খারাপ কোড নয়। আমি বেশ ঘন ঘন সি ফাংশন ব্যবহার। উদাহরণস্বরূপ, printf এবং scanf উভয় std::cin এবং std::cout (উল্লেখযোগ্য) এর চেয়ে দ্রুততর, fopen সিনট্যাক্স বাইনারি ধরনের জন্য অনেক বেশি বন্ধুত্বপূর্ণ এবং তারা ছোট EXEs উত্পাদন করতে থাকে।

এই "কর্মক্ষমতা উপর লক্ষণ" চুক্তি বিক্রি করবেন না।


যাদের সাথে এটি কোড সাইজের জন্য সমস্ত দক্ষতা উত্সর্গ করার জন্য ভালভাবে বসতে পারে না এবং কমনীয়তার একটি ধরন হিসাবে "দক্ষ" দেখতে, নীচের একটি মিষ্টি স্থান আঘাত করতে হবে (এবং আমি মনে করি যে টেমপ্লেট ধারক ক্লাসটি একটি চমত্কার মার্জিত সংযোজন।):

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

আমি সাধারণত আমার দ্বিতীয় প্যারামিটার ( ContainerT ) হিসাবে std::vector<std::string> ধরনগুলি ব্যবহার করতে পছন্দ করি ... তবে সরাসরি অ্যাক্সেসের প্রয়োজন নেই এমন list<> vector<> চেয়ে দ্রুততর উপায়, এবং আপনি এমনকি তৈরি করতে পারেন আপনার নিজস্ব স্ট্রিং ক্লাস এবং std::list<subString> মতো কিছু ব্যবহার std::list<subString> যেখানে subString অবিশ্বাস্য গতি বৃদ্ধির জন্য কোন কপি করে না।

এটি এই পৃষ্ঠাতে দ্রুততম টোকেনাইজ হিসাবে দ্রুত যত দ্রুত এবং দ্বিগুণ এবং কিছু অন্যদের চেয়ে প্রায় 5 গুণ দ্রুত। এছাড়াও নিখুঁত পরামিতি ধরনের সঙ্গে আপনি অতিরিক্ত গতি বৃদ্ধির জন্য সব স্ট্রিং এবং তালিকা কপি নিষ্কাশন করতে পারেন।

উপরন্তু এটি ফলাফল (অত্যন্ত অদক্ষ) ফলাফলটি ফেরত দেয় না, বরং এটি একটি রেফারেন্স হিসাবে টোকেনগুলি পাস করে, এভাবে আপনি যদি কামনা করেন তবে একাধিক কল ব্যবহার করে আপনি টোকেনগুলি তৈরি করতে পারবেন।

অবশেষে এটি আপনাকে একটি নির্দিষ্ট ঐচ্ছিক প্যারামিটারের মাধ্যমে ফলাফল থেকে খালি টোকেনগুলি ট্রিম করতে হবে কিনা তা নির্দিষ্ট করতে দেয়।

এটি সমস্ত প্রয়োজন std::string ... বাকি ঐচ্ছিক। এটি স্ট্রিম বা বুস্ট লাইব্রেরি ব্যবহার করে না, তবে স্বাভাবিকভাবেই এটির কিছু বিদেশী প্রকার গ্রহণ করতে সক্ষম।


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

std::stringstream ব্যবহার করে যেমন আপনি পুরোপুরি সূক্ষ্ম কাজ করেছেন, এবং আপনি যা চান তা ঠিক করুন। যদিও আপনি শুধু কিছু করার জন্য ভিন্ন উপায় খুঁজছেন, আপনি std::find_first_of() / std::find_first_of() এবং std::string::substr() ব্যবহার করতে পারেন।

এখানে একটি উদাহরণ:

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

আমি এই টাস্কের জন্য বুস্ট / রেজেক্স পদ্ধতিগুলি ব্যবহার করতে চাই কারণ তারা বিভাজন মানদণ্ডের জন্য সর্বাধিক নমনীয়তা সরবরাহ করে।

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

এটা করার অন্য উপায় এখানে ..

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

ডিলিমিটার হিসাবে যেকোনো স্ট্রিং ব্যবহার করতে পারেন, বাইনারি ডেটা দিয়েও এটি ব্যবহার করা যেতে পারে (std :: string বাইনারি ডেটা সমর্থন করে, নুল সহ)

ব্যবহার:

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

আউটপুট:

this
is
!example!string

আমি strtok ব্যবহার করে আমার নিজের ঘূর্ণিত করেছি এবং একটি স্ট্রিং বিভক্ত ব্যবহার boost। আমার সবচেয়ে ভাল পদ্ধতি হল সি ++ স্ট্রিং টুলকিট লাইব্রেরি । এটা অবিশ্বাস্যভাবে নমনীয় এবং দ্রুত।

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

টুলকিটটিতে এই সহজ উদাহরণটি দেখানোর চেয়ে অনেক বেশি নমনীয়তা রয়েছে তবে দরকারী উপাদানের মধ্যে একটি স্ট্রিং বিশ্লেষণে এর উপযোগিতা অবিশ্বাস্য।


আমি এটি তৈরি করেছি কারণ আমার স্ট্রিং এবং সি-ভিত্তিক স্ট্রিংগুলি বিভক্ত করার একটি সহজ উপায় দরকার ... আশা করছি অন্য কেউ এটিও দরকারী হিসাবে খুঁজে পেতে পারে। এছাড়াও এটি টোকেনগুলির উপর নির্ভর করে না এবং আপনি ক্ষেত্রগুলিকে delimiters হিসাবে ব্যবহার করতে পারেন, যা আমার প্রয়োজনীয় অন্য একটি কী।

আমি নিশ্চিত যে তার উন্নতির আরও উন্নতির জন্য এমন উন্নতি রয়েছে যা দয়া করে সব উপায়ে করুন

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

আমি আশা করি অন্য কেউ এটি হিসাবে দরকারী হিসাবে আমার খুঁজে পেতে পারেন।


নীচের কোডটি 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;
}

সম্প্রতি আমি একটি উট-cased শব্দ subwords মধ্যে বিভক্ত ছিল। কোন 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" কে "এ", "কোয়েরি" এবং "ব্যবসায়" তে বিভক্ত করে। ফাংশন সংকীর্ণ এবং প্রশস্ত স্ট্রিং সঙ্গে কাজ করে। কারন এটি বর্তমান লোকেলকে সম্মান করে কারণ "রুমফাহার্টুবারউচুং ভেরর্ডনং" "রুমফাহার্ট", ​​"Überwachungs" এবং "Verordnung" তে বিভক্ত।

নোট std::upperসত্যিই ফাংশন টেমপ্লেট যুক্তি হিসাবে পাস করা উচিত। তারপর এই ফাংশন থেকে আরো সাধারণকরণ delimiters মত বিভক্ত ",", ";"বা " "খুব।







split