457

Java には便利な分割メソッドがあります。

String str = "The quick brown fox";
String[] results = str.split(" ");

C++ でこれを行う簡単な方法はありますか?

4

35 に答える 35

191

Boost トークナイザークラスは、この種のことを非常に単純にすることができます。

#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>

using namespace std;
using namespace boost;

int main(int, char**)
{
    string text = "token, test   string";

    char_separator<char> sep(", ");
    tokenizer< char_separator<char> > tokens(text, sep);
    BOOST_FOREACH (const string& t, tokens) {
        cout << t << "." << endl;
    }
}

C++11 用に更新:

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

using namespace std;
using namespace boost;

int main(int, char**)
{
    string text = "token, test   string";

    char_separator<char> sep(", ");
    tokenizer<char_separator<char>> tokens(text, sep);
    for (const auto& t : tokens) {
        cout << t << "." << endl;
    }
}
于 2008-09-11T02:10:33.463 に答える
178

これが本当に単純なものです:

#include <vector>
#include <string>
using namespace std;

vector<string> split(const char *str, char c = ' ')
{
    vector<string> result;

    do
    {
        const char *begin = str;

        while(*str != c && *str)
            str++;

        result.push_back(string(begin, str));
    } while (0 != *str++);

    return result;
}
于 2008-09-10T12:30:06.680 に答える
166

C ++標準ライブラリのアルゴリズムは、具体的なコンテナではなく、イテレータに基づいています。split残念ながら、これが便利だと誰も主張していなくても、C++標準ライブラリでJavaのような関数を提供することは困難です。しかし、そのリターンタイプは何でしょうか?std::vector<std::basic_string<…&gt;>?たぶん、しかしそれから私たちは(潜在的に冗長で費用のかかる)割り当てを実行することを余儀なくされます。

代わりに、C ++は、任意の複雑な区切り文字に基づいて文字列を分割する方法を多数提供していますが、他の言語ほどうまくカプセル化されているものはありません。ブログ投稿全体を埋める方法はたくさんあります。

std::string::find最も単純な方法では、を押すまでを使用して繰り返し、を使用std::string::nposしてコンテンツを抽出できますstd::string::substr

空白で分割するためのより流動的な(そして慣用的ですが基本的な)バージョンは、:を使用しますstd::istringstream

auto iss = std::istringstream{"The quick brown fox"};
auto str = std::string{};

while (iss >> str) {
    process(str);
}

std::istream_iteratorsを使用すると、文字列ストリームの内容をイテレータ範囲コンストラクターを使用してベクトルにコピーすることもできます。

複数のライブラリ(Boost.Tokenizerなど)は、特定のトークナイザーを提供します。

より高度な分割には正規表現が必要です。C ++は、std::regex_token_iterator特にこの目的のためにを提供します。

auto const str = "The quick brown fox"s;
auto const re = std::regex{R"(\s+)"};
auto const vec = std::vector<std::string>(
    std::sregex_token_iterator{begin(str), end(str), re, -1},
    std::sregex_token_iterator{}
);
于 2008-09-10T12:18:25.383 に答える
136

別の簡単な方法は、 を使用することgetlineです。何かのようなもの:

stringstream ss("bla bla");
string s;

while (getline(ss, s, ' ')) {
 cout << s << endl;
}

split()必要に応じて、 を返す簡単なメソッドを作成できますvector<string>。これは非常に便利です。

于 2008-11-28T04:17:39.937 に答える
117

strtokを使用します。私の意見では、strtokが必要なものを提供しない限り、トークン化を中心にクラスを構築する必要はありません。そうではないかもしれませんが、CおよびC ++でさまざまな構文解析コードを記述してから15年以上、私は常にstrtokを使用してきました。これが例です

char myString[] = "The quick brown fox";
char *p = strtok(myString, " ");
while (p) {
    printf ("Token: %s\n", p);
    p = strtok(NULL, " ");
}

いくつかの注意点(ニーズに合わない場合があります)。文字列はその過程で「破棄」されます。つまり、EOS文字はデリムタースポットにインラインで配置されます。正しい使用法では、文字列の非定数バージョンを作成する必要がある場合があります。解析中に区切り文字のリストを変更することもできます。

私自身の意見では、上記のコードは、別のクラスを作成するよりもはるかに単純で使いやすいと思います。私にとって、これは言語が提供する機能の1つであり、それを適切かつクリーンに実行します。これは単に「Cベース」のソリューションです。それは適切で、簡単で、余分なコードをたくさん書く必要はありません:-)

于 2008-09-10T13:37:33.507 に答える
85

ストリーム、イテレータ、およびコピーアルゴリズムを使用して、これをかなり直接行うことができます。

#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>

int main()
{
  std::string str = "The quick brown fox";

  // construct a stream from the string
  std::stringstream strstr(str);

  // use stream iterators to copy the stream to the vector as whitespace separated strings
  std::istream_iterator<std::string> it(strstr);
  std::istream_iterator<std::string> end;
  std::vector<std::string> results(it, end);

  // send the vector to stdout.
  std::ostream_iterator<std::string> oit(std::cout);
  std::copy(results.begin(), results.end(), oit);
}
于 2008-09-10T12:46:14.193 に答える
49

気分を害する人はいませんが、このような単純な問題に対して、あなたは物事を複雑にしすぎています。Boostを使用する理由はたくさんあります。しかし、これほど単純なことは、20# のそりでハエを打つようなものです。

void
split( vector<string> & theStringVector,  /* Altered/returned value */
       const  string  & theString,
       const  string  & theDelimiter)
{
    UASSERT( theDelimiter.size(), >, 0); // My own ASSERT macro.

    size_t  start = 0, end = 0;

    while ( end != string::npos)
    {
        end = theString.find( theDelimiter, start);

        // If at end, use length=maxLength.  Else use length=end-start.
        theStringVector.push_back( theString.substr( start,
                       (end == string::npos) ? string::npos : end - start));

        // If at end, use start=maxSize.  Else use start=end+delimiter.
        start = (   ( end > (string::npos - theDelimiter.size()) )
                  ?  string::npos  :  end + theDelimiter.size());
    }
}

たとえば (Doug の場合)、

#define SHOW(I,X)   cout << "[" << (I) << "]\t " # X " = \"" << (X) << "\"" << endl

int
main()
{
    vector<string> v;

    split( v, "A:PEP:909:Inventory Item", ":" );

    for (unsigned int i = 0;  i < v.size();   i++)
        SHOW( i, v[i] );
}

そうです、split() でベクターを渡すのではなく、新しいベクターを返すようにすることもできます。ラップしてオーバーロードするのは簡単です。しかし、私が何をしているかによっては、常に新しいオブジェクトを作成するよりも、既存のオブジェクトを再利用する方が良いことがよくあります。(間にベクターを空にすることを忘れない限り!)

参照: http://www.cplusplus.com/reference/string/string/ .

(私はもともと Doug の質問への回答を書いていました: C++ Strings Modifying and Extracting based on Separators (closed)。しかし、Martin York がその質問をここにポインタで閉じたので...私は自分のコードを一般化します。)

于 2008-11-28T02:55:51.117 に答える
38

Boostには強力な分割機能があります: boost::algorithm::split

サンプルプログラム:

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

int main() {
    auto s = "a,b, c ,,e,f,";
    std::vector<std::string> fields;
    boost::split(fields, s, boost::is_any_of(","));
    for (const auto& field : fields)
        std::cout << "\"" << field << "\"\n";
    return 0;
}

出力:

"a"
"b"
" c "
""
"e"
"f"
""
于 2008-09-12T17:20:23.253 に答える
28

あなたがC++ソリューションを求めたことは知っていますが、これは役立つと思うかもしれません。

Qt

#include <QString>

...

QString str = "The quick brown fox"; 
QStringList results = str.split(" "); 

この例でのBoostに対する利点は、投稿のコードへの直接の1対1のマッピングであるということです。

Qtのドキュメントで詳細を参照してください

于 2010-08-04T17:34:03.780 に答える
23

これがあなたが望むことをするかもしれないサンプルのトークナイザークラスです

//Header file
class Tokenizer 
{
    public:
        static const std::string DELIMITERS;
        Tokenizer(const std::string& str);
        Tokenizer(const std::string& str, const std::string& delimiters);
        bool NextToken();
        bool NextToken(const std::string& delimiters);
        const std::string GetToken() const;
        void Reset();
    protected:
        size_t m_offset;
        const std::string m_string;
        std::string m_token;
        std::string m_delimiters;
};

//CPP file
const std::string Tokenizer::DELIMITERS(" \t\n\r");

Tokenizer::Tokenizer(const std::string& s) :
    m_string(s), 
    m_offset(0), 
    m_delimiters(DELIMITERS) {}

Tokenizer::Tokenizer(const std::string& s, const std::string& delimiters) :
    m_string(s), 
    m_offset(0), 
    m_delimiters(delimiters) {}

bool Tokenizer::NextToken() 
{
    return NextToken(m_delimiters);
}

bool Tokenizer::NextToken(const std::string& delimiters) 
{
    size_t i = m_string.find_first_not_of(delimiters, m_offset);
    if (std::string::npos == i) 
    {
        m_offset = m_string.length();
        return false;
    }

    size_t j = m_string.find_first_of(delimiters, i);
    if (std::string::npos == j) 
    {
        m_token = m_string.substr(i);
        m_offset = m_string.length();
        return true;
    }

    m_token = m_string.substr(i, j - i);
    m_offset = j;
    return true;
}

例:

std::vector <std::string> v;
Tokenizer s("split this string", " ");
while (s.NextToken())
{
    v.push_back(s.GetToken());
}
于 2008-09-10T12:18:14.493 に答える
16

pystringは、split メソッドを含む一連の Python の文字列関数を実装する小さなライブラリです。

#include <string>
#include <vector>
#include "pystring.h"

std::vector<std::string> chunks;
pystring::split("this string", chunks);

// also can specify a separator
pystring::split("this-string", chunks, "-");
于 2011-12-29T15:17:58.177 に答える
8

Adam Pierce の答えは、const char*. の end イテレータが undefined であるため、イテレータを使用するのは少し問題がありますstring。とはいえ、string str{ "The quick brown fox" }これを確実に達成できるとすれば、次のとおりです。

auto start = find(cbegin(str), cend(str), ' ');
vector<string> tokens{ string(cbegin(str), start) };

while (start != cend(str)) {
    const auto finish = find(++start, cend(str), ' ');

    tokens.push_back(string(start, finish));
    start = finish;
}

Live Example


On Freund が示唆 するように、標準機能を使用して複雑さを抽象化することを検討している場合strtokは、単純なオプションです。

vector<string> tokens;

for (auto i = strtok(data(str), " "); i != nullptr; i = strtok(nullptr, " ")) tokens.push_back(i);

C++17 にアクセスできない場合はdata(str)、次の例のように置き換える必要があります: http://ideone.com/8kAGoa

例では示されていませんが、strtok各トークンに同じ区切り文字を使用する必要はありません。ただし、この利点に加えて、いくつかの欠点があります。

  1. strtokstrings同時に複数で使用することはできません:nullptr現在のトークン化を続行するには a を渡すか、トークン化するにstringは newchar*を渡す必要があります (ただし、これをサポートする非標準の実装がいくつかあります。たとえば: strtok_s)
  2. 同じ理由strtokで、複数のスレッドで同時に使用することはできません (ただし、これは実装で定義されている場合があります。たとえば、Visual Studio の実装はスレッド セーフです) 。
  3. を呼び出すと操作対象がstrtok変更されるため、 s、s、またはリテラル文字列でこれらのいずれかをトークン化したり、内容を保持する必要がある人を操作したりするためにstring使用することはできません。コピーする必要があります。手術を受けるconst stringconst char*strtokstringstr

split_viewは、非破壊的な方法で文字列をトークン化する機能を提供します: https://topanswers.xyz/cplusplus?q=749#a874


前のメソッドは、トークン化vectorされたインプレースを生成できません。つまり、それらをヘルパー関数に抽象化しないと、初期化できませんconst vector<string> tokens。その機能空白区切り文字を受け入れる機能istream_iterator、 . たとえば、次のconst string str{ "The quick \tbrown \nfox" }ようにします。

istringstream is{ str };
const vector<string> tokens{ istream_iterator<string>(is), istream_iterator<string>() };

Live Example

このオプションに必要な の構築にはistringstream、前の 2 つのオプションよりもはるかに大きなコストがかかりますが、このコストは通常​​、string割り当ての費用に隠されています。


上記のオプションのいずれもトークン化のニーズに十分に柔軟に対応できない場合、最も柔軟なオプションはregex_token_iteratorもちろん、この柔軟性を使用するとより多くの費用がかかりますが、これもstring割り当てコストに隠されている可能性があります。たとえば、次の入力が与えられた場合、エスケープされていないコンマに基づいてトークン化し、空白も食べるとします。const string str{ "The ,qu\\,ick ,\tbrown, fox" }これを実行できます。

const regex re{ "\\s*((?:[^\\\\,]|\\\\.)*?)\\s*(?:,|$)" };
const vector<string> tokens{ sregex_token_iterator(cbegin(str), cend(str), re, 1), sregex_token_iterator() };

Live Example

于 2016-07-26T16:51:20.057 に答える
7

この例を確認してください。それはあなたを助けるかもしれません..

#include <iostream>
#include <sstream>

using namespace std;

int main ()
{
    string tmps;
    istringstream is ("the dellimiter is the space");
    while (is.good ()) {
        is >> tmps;
        cout << tmps << "\n";
    }
    return 0;
}
于 2010-12-20T12:25:35.623 に答える
6

MFC/ATLには非常に優れたトークナイザーがあります。MSDNから:

CAtlString str( "%First Second#Third" );
CAtlString resToken;
int curPos= 0;

resToken= str.Tokenize("% #",curPos);
while (resToken != "")
{
   printf("Resulting token: %s\n", resToken);
   resToken= str.Tokenize("% #",curPos);
};

Output

Resulting Token: First
Resulting Token: Second
Resulting Token: Third
于 2009-03-22T02:28:16.377 に答える
4

ここに多くの過度に複雑な提案。この単純なstd::stringソリューションを試してください:

using namespace std;

string someText = ...

string::size_type tokenOff = 0, sepOff = tokenOff;
while (sepOff != string::npos)
{
    sepOff = someText.find(' ', sepOff);
    string::size_type tokenLen = (sepOff == string::npos) ? sepOff : sepOff++ - tokenOff;
    string token = someText.substr(tokenOff, tokenLen);
    if (!token.empty())
        /* do something with token */;
    tokenOff = sepOff;
}
于 2012-08-01T05:50:39.210 に答える
4

Cを使用する場合は、 strtok関数を使用できます。マルチスレッドを使用する場合は、注意が必要です。

于 2008-09-10T12:23:33.903 に答える
4

簡単なものについては、次を使用します。

unsigned TokenizeString(const std::string& i_source,
                        const std::string& i_seperators,
                        bool i_discard_empty_tokens,
                        std::vector<std::string>& o_tokens)
{
    unsigned prev_pos = 0;
    unsigned pos = 0;
    unsigned number_of_tokens = 0;
    o_tokens.clear();
    pos = i_source.find_first_of(i_seperators, pos);
    while (pos != std::string::npos)
    {
        std::string token = i_source.substr(prev_pos, pos - prev_pos);
        if (!i_discard_empty_tokens || token != "")
        {
            o_tokens.push_back(i_source.substr(prev_pos, pos - prev_pos));
            number_of_tokens++;
        }

        pos++;
        prev_pos = pos;
        pos = i_source.find_first_of(i_seperators, pos);
    }

    if (prev_pos < i_source.length())
    {
        o_tokens.push_back(i_source.substr(prev_pos));
        number_of_tokens++;
    }

    return number_of_tokens;
}

卑怯な免責事項: 私は、バイナリ ファイル、ソケット、または何らかの API 呼び出し (I/O カード、カメラ) を介してデータを受け取るリアルタイム データ処理ソフトウェアを作成しています。この関数を、起動時に外部構成ファイルを読み取るよりも複雑または時間が重要な目的で使用することはありません。

于 2008-09-15T15:28:39.003 に答える
4

正規表現ライブラリを使用するだけで、正規表現を使用して解決できます。

式 (\w+) と \1 (正規表現のライブラリ実装によっては $1) の変数を使用します。

于 2011-04-22T00:14:36.273 に答える
3

>>私はそれが文字列ストリームの演算子の目的だと思いました:

string word; sin >> word;
于 2008-09-10T12:43:56.740 に答える
2

空のトークンを含めるか (strsep のように)、除外するか (strtok のように) を制御できるアプローチを次に示します。

#include <string.h> // for strchr and strlen

/*
 * want_empty_tokens==true  : include empty tokens, like strsep()
 * want_empty_tokens==false : exclude empty tokens, like strtok()
 */
std::vector<std::string> tokenize(const char* src,
                                  char delim,
                                  bool want_empty_tokens)
{
  std::vector<std::string> tokens;

  if (src and *src != '\0') // defensive
    while( true )  {
      const char* d = strchr(src, delim);
      size_t len = (d)? d-src : strlen(src);

      if (len or want_empty_tokens)
        tokens.push_back( std::string(src, len) ); // capture token

      if (d) src += len+1; else break;
    }

  return tokens;
}
于 2012-10-26T15:14:10.370 に答える
1

boost::make_find_iterator を利用できます。これに似たもの:

template<typename CH>
inline vector< basic_string<CH> > tokenize(
    const basic_string<CH> &Input,
    const basic_string<CH> &Delimiter,
    bool remove_empty_token
    ) {

    typedef typename basic_string<CH>::const_iterator string_iterator_t;
    typedef boost::find_iterator< string_iterator_t > string_find_iterator_t;

    vector< basic_string<CH> > Result;
    string_iterator_t it = Input.begin();
    string_iterator_t it_end = Input.end();
    for(string_find_iterator_t i = boost::make_find_iterator(Input, boost::first_finder(Delimiter, boost::is_equal()));
        i != string_find_iterator_t();
        ++i) {
        if(remove_empty_token){
            if(it != i->begin())
                Result.push_back(basic_string<CH>(it,i->begin()));
        }
        else
            Result.push_back(basic_string<CH>(it,i->begin()));
        it = i->end();
    }
    if(it != it_end)
        Result.push_back(basic_string<CH>(it,it_end));

    return Result;
}
于 2011-08-03T06:58:13.573 に答える
0

boost::tokenizerはあなたの友人ですが、国際化 (i18n) の問題を参照して、従来の/型の代わりにwstring/を使用して、コードを移植可能にすることを検討してください。wchar_tstringchar

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

using namespace std;
using namespace boost;

typedef tokenizer<char_separator<wchar_t>,
                  wstring::const_iterator, wstring> Tok;

int main()
{
  wstring s;
  while (getline(wcin, s)) {
    char_separator<wchar_t> sep(L" "); // list of separator characters
    Tok tok(s, sep);
    for (Tok::iterator beg = tok.begin(); beg != tok.end(); ++beg) {
      wcout << *beg << L"\t"; // output (or store in vector)
    }
    wcout << L"\n";
  }
  return 0;
}
于 2012-07-16T01:14:11.680 に答える
0

トークン化する入力文字列の最大長がわかっている場合は、これを利用して非常に高速なバージョンを実装できます。以下に基本的なアイデアをスケッチします。これは、strtok() と、Jon Bentley の「プログラミング Perls」第 2 版、第 15 章で説明されている「接尾辞配列」データ構造の両方に触発されたものです。この場合の C++ クラスは、編成と利便性を提供するだけです。使用の。示されている実装は、トークンの先頭と末尾の空白文字を削除するために簡単に拡張できます。

基本的に、区切り文字を文字列終了の '\0' 文字に置き換え、変更された文字列を使用してトークンへのポインターを設定できます。文字列がセパレーターのみで構成される極端なケースでは、string-length に 1 を加えた結果の空のトークンが得られます。変更する文字列を複製することは実用的です。

ヘッダー ファイル:

class TextLineSplitter
{
public:

    TextLineSplitter( const size_t max_line_len );

    ~TextLineSplitter();

    void            SplitLine( const char *line,
                               const char sep_char = ',',
                             );

    inline size_t   NumTokens( void ) const
    {
        return mNumTokens;
    }

    const char *    GetToken( const size_t token_idx ) const
    {
        assert( token_idx < mNumTokens );
        return mTokens[ token_idx ];
    }

private:
    const size_t    mStorageSize;

    char           *mBuff;
    char          **mTokens;
    size_t          mNumTokens;

    inline void     ResetContent( void )
    {
        memset( mBuff, 0, mStorageSize );
        // mark all items as empty:
        memset( mTokens, 0, mStorageSize * sizeof( char* ) );
        // reset counter for found items:
        mNumTokens = 0L;
    }
};

実装ファイル:

TextLineSplitter::TextLineSplitter( const size_t max_line_len ):
    mStorageSize ( max_line_len + 1L )
{
    // allocate memory
    mBuff   = new char  [ mStorageSize ];
    mTokens = new char* [ mStorageSize ];

    ResetContent();
}

TextLineSplitter::~TextLineSplitter()
{
    delete [] mBuff;
    delete [] mTokens;
}


void TextLineSplitter::SplitLine( const char *line,
                                  const char sep_char   /* = ',' */,
                                )
{
    assert( sep_char != '\0' );

    ResetContent();
    strncpy( mBuff, line, mMaxLineLen );

    size_t idx       = 0L; // running index for characters

    do
    {
        assert( idx < mStorageSize );

        const char chr = line[ idx ]; // retrieve current character

        if( mTokens[ mNumTokens ] == NULL )
        {
            mTokens[ mNumTokens ] = &mBuff[ idx ];
        } // if

        if( chr == sep_char || chr == '\0' )
        { // item or line finished
            // overwrite separator with a 0-terminating character:
            mBuff[ idx ] = '\0';
            // count-up items:
            mNumTokens ++;
        } // if

    } while( line[ idx++ ] );
}

使用シナリオは次のとおりです。

// create an instance capable of splitting strings up to 1000 chars long:
TextLineSplitter spl( 1000 );
spl.SplitLine( "Item1,,Item2,Item3" );
for( size_t i = 0; i < spl.NumTokens(); i++ )
{
    printf( "%s\n", spl.GetToken( i ) );
}

出力:

Item1

Item2
Item3
于 2011-05-15T20:47:07.477 に答える
0

単純な C++ コード (標準 C++98)、複数の区切り文字 (std::string で指定) を受け入れ、ベクトル、文字列、および反復子のみを使用します。

#include <iostream>
#include <vector>
#include <string>
#include <stdexcept> 

std::vector<std::string> 
split(const std::string& str, const std::string& delim){
    std::vector<std::string> result;
    if (str.empty())
        throw std::runtime_error("Can not tokenize an empty string!");
    std::string::const_iterator begin, str_it;
    begin = str_it = str.begin(); 
    do {
        while (delim.find(*str_it) == std::string::npos && str_it != str.end())
            str_it++; // find the position of the first delimiter in str
        std::string token = std::string(begin, str_it); // grab the token
        if (!token.empty()) // empty token only when str starts with a delimiter
            result.push_back(token); // push the token into a vector<string>
        while (delim.find(*str_it) != std::string::npos && str_it != str.end())
            str_it++; // ignore the additional consecutive delimiters
        begin = str_it; // process the remaining tokens
        } while (str_it != str.end());
    return result;
}

int main() {
    std::string test_string = ".this is.a.../.simple;;test;;;END";
    std::string delim = "; ./"; // string containing the delimiters
    std::vector<std::string> tokens = split(test_string, delim);           
    for (std::vector<std::string>::const_iterator it = tokens.begin(); 
        it != tokens.end(); it++)
            std::cout << *it << std::endl;
}
于 2013-12-15T01:09:58.677 に答える
0
/// split a string into multiple sub strings, based on a separator string
/// for example, if separator="::",
///
/// s = "abc" -> "abc"
///
/// s = "abc::def xy::st:" -> "abc", "def xy" and "st:",
///
/// s = "::abc::" -> "abc"
///
/// s = "::" -> NO sub strings found
///
/// s = "" -> NO sub strings found
///
/// then append the sub-strings to the end of the vector v.
/// 
/// the idea comes from the findUrls() function of "Accelerated C++", chapt7,
/// findurls.cpp
///
void split(const string& s, const string& sep, vector<string>& v)
{
    typedef string::const_iterator iter;
    iter b = s.begin(), e = s.end(), i;
    iter sep_b = sep.begin(), sep_e = sep.end();

    // search through s
    while (b != e){
        i = search(b, e, sep_b, sep_e);

        // no more separator found
        if (i == e){
            // it's not an empty string
            if (b != e)
                v.push_back(string(b, e));
            break;
        }
        else if (i == b){
            // the separator is found and right at the beginning
            // in this case, we need to move on and search for the
            // next separator
            b = i + sep.length();
        }
        else{
            // found the separator
            v.push_back(string(b, i));
            b = i;
        }
    }
}

ブースト ライブラリは優れていますが、常に利用できるとは限りません。この種のことを手で行うことは、良い頭の体操でもあります。ここでは、STL の std::search() アルゴリズムを使用するだけです。上記のコードを参照してください。

于 2014-02-25T06:40:51.927 に答える