8

文字列をトークン化する C++ で何かを書きたいと思います。私が何を望んでいるかを説明するには、次の文字列を使用します。

add string "this is a string with spaces!"

これは次のように分割する必要があります。

add
string
this is a string with spaces!

標準ライブラリベースの迅速なアプローチはありますか?

4

8 に答える 8

8

ライブラリは必要ありません。繰り返しでタスクを実行できます(説明したほど単純な場合)。

string str = "add string \"this is a string with space!\"";

for( size_t i=0; i<str.length(); i++){

    char c = str[i];
    if( c == ' ' ){
        cout << endl;
    }else if(c == '\"' ){
        i++;
        while( str[i] != '\"' ){ cout << str[i]; i++; }
    }else{
        cout << c;
    }
}

それが出力する

add
string
this is a string with space!
于 2013-09-07T16:33:47.337 に答える
5

ここに完全な関数があります。必要に応じて変更してください。文字列の一部をベクトルstrings( qargs)に追加します。

void split_in_args(std::vector<std::string>& qargs, std::string command){
        int len = command.length();
        bool qot = false, sqot = false;
        int arglen;
        for(int i = 0; i < len; i++) {
                int start = i;
                if(command[i] == '\"') {
                        qot = true;
                }
                else if(command[i] == '\'') sqot = true;

                if(qot) {
                        i++;
                        start++;
                        while(i<len && command[i] != '\"')
                                i++;
                        if(i<len)
                                qot = false;
                        arglen = i-start;
                        i++;
                }
                else if(sqot) {
                        i++;
                        start++;
                        while(i<len && command[i] != '\'')
                                i++;
                        if(i<len)
                                sqot = false;
                        arglen = i-start;
                        i++;
                }
                else{
                        while(i<len && command[i]!=' ')
                                i++;
                        arglen = i-start;
                }
                qargs.push_back(command.substr(start, arglen));
        }
        for(int i=0;i<qargs.size();i++){
                std::cout<<qargs[i]<<std::endl;
        }
        std::cout<<qargs.size();
        if(qot || sqot) std::cout<<"One of the quotes is open\n";
}
于 2016-03-30T06:20:30.133 に答える
2

Boost ライブラリにはtokenizerescaped_list_separator. これらの組み合わせは、探しているものを提供するように見えます。

これは、この投稿の時点で最新のブースト ドキュメントへのリンクであり、これを読んだ時点ではほぼ確実に古いバージョンです。

https://www.boost.org/doc/libs/1_73_0/libs/tokenizer/doc/tokenizer.htm

https://www.boost.org/doc/libs/1_73_0/libs/tokenizer/doc/escaped_list_separator.htm

この例は、boost のドキュメントから抜粋したものです。私自身の例を作成していないことを許してください。

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

int main(){
   using namespace std;
   using namespace boost;
   string s = "Field 1,\"putting quotes around fields, allows commas\",Field 3";
   tokenizer<escaped_list_separator<char> > tok(s);
   for(tokenizer<escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg){
       cout << *beg << "\n";
   }
}
于 2020-06-10T22:05:28.997 に答える
0

標準ライブラリには簡単なアプローチはないと思います。間接的に次のアルゴリズムが機能します。

a) で '\"' をstring::find('\"')検索します。何か見つかった場合は を使用して次の '\"' を検索しstring::find('\'',prevIndex)、見つかった場合は を使用しますstring::substr()。元の文字列からその部分を破棄します。

b)' '同じ方法で文字を検索します。

注: 文字列全体を反復処理する必要があります。

于 2013-09-07T16:30:46.677 に答える