1

重複の可能性:
C++で文字列を分割する

私は文字列を持っています:次の
14332x+32x=10
ように分割したいと思います:
[14332][+32][10]
これまでのところ、私はやってみました

char c;
std::stringstream ss(equation1);
while (ss >> c) {
    std::cout << c << std::endl;
} 

しかし、それが何を印刷するかをテストした後、私はその情報から行うことは不可能だと思います。xと=で文字列を分割する必要があることは知っていますが、それが可能かどうか、またそれがどのように行われるかはわかりません。私はそれをグーグルで検索しましたが、役立つと思われるものは見つかりませんでしたが、私はあまりにもc ++であり、答えは私の目の前にあるかもしれません。
ブーストは使いたくない。どんなアドバイスも役に立ちます!

4

5 に答える 5

4

空白文字として指定するファセットの使用を検討してくださいx=

#include <locale>
#include <iostream>
#include <sstream>

struct punct_ctype : std::ctype<char> {
  punct_ctype() : std::ctype<char>(get_table()) {}
  static mask const* get_table()
  {
    static mask rc[table_size];
    rc[' '] = std::ctype_base::space;
    rc['\n'] = std::ctype_base::space;
    rc['x'] = std::ctype_base::space;
    rc['='] = std::ctype_base::space;
    return &rc[0];
  }
};

int main() {
  std::string equation;
  while(std::getline(std::cin, equation)) {
    std::istringstream ss(equation);
    ss.imbue(std::locale(ss.getloc(), new punct_ctype));
    std::string term;
    while(ss >> term) {
      std::cout << "[" << term << "]";
    }
    std::cout << "\n";
  }
}
于 2013-01-31T02:21:43.527 に答える
1

手動の方法は、文字列内の各文字に対して for ループを実行し、文字が == 文字の場合は、新しい文字列にコピーして分割することです (>1 分割が予想される場合は、文字列のリスト/配列を使用します)。

また、標準は文字機能によって分割されていると思います。そうでない場合、stringstream::GetLine() には分割する文字を受け取るオーバーロードがあり、スペースは無視されます。

GetLine() はとても良いです:)

于 2013-01-31T01:15:20.807 に答える
1

sscanf次のように使用できます。

sscanf(s.c_str(), "%[^x]x%[^x]x=%s", a, b, c);

where%[^x]は「x 以外の任意の文字」を表します。記号(つまりなど)を気にせず+、数字だけを気にする場合は、次のようにすることができます:

sscanf(s.c_str(), "%dx%dx=%d", &x, &y, &z);
于 2013-01-31T01:41:27.113 に答える
0

C++11 を使用してもかまわない場合は、次のようなものを使用できます。

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

typedef std::vector<std::string> strings;
typedef std::unordered_set<char> tokens;

struct tokenize
{
    tokenize(strings& output,const tokens& t) : 
    v_(output),
    t_(t)
    {}        
    ~tokenize()
    {
        if(!s.empty())
            v_.push_back(s);
    }
    void operator()(const char &c)
    {
        if(t_.find(c)!=t_.end())
        {
            if(!s.empty())
                v_.push_back(s);
            s="";
        }
        else
        {
            s = s + c;
        }
    }
    private:
    std::string s;
    strings& v_;
    const tokens& t_;
};

void split(const std::string& input, strings& output, const tokens& t )
{
    tokenize tokenizer(output,t);
    for( auto i : input )
    {
        tokenizer(i);
    }
}

int main()
{
    strings tokenized;
    tokens t;
    t.insert('x');
    t.insert('=');
    std::string input = "14332x+32x=10";
    split(input,tokenized,t);
    for( auto i : tokenized )
    {
        std::cout<<"["<<i<<"]";
    }
    return 0;
}

上記のコードへの Ideone リンク: http://ideone.com/17g75F

于 2013-01-31T02:29:41.777 に答える
0

次のようなことを可能にする単純で基本的なトークン化機能を提供する関数については、この SO 回答をgetline_until()参照してください。

#include <string>
#include <stringstream>

#include "getline_until.h"

int main()
{
    std::string equation1("14332x+32x=10");
    std::stringstream ss(equation1);

    std::string token;
    while (getline_until(ss, token, "x=")) {
        if (!token.empty()) std::cout << "[" << token << "]";
    } 

    std::cout << std::endl;
}

このgetline_until()関数を使用すると、 のような区切り記号のリストを指定できますstrtok()(ただし、getline_until()のような区切り記号の実行をスキップするのではなく、空のトークンを返しますstrtok())。または、関数を使用してトークンをいつ区切るかを決定できる述語を提供することもできます。

それがあなたにさせないことの1つは(再び-strtok()または標準に似ていますgetline())、単にコンテキストでトークンを分割することです-破棄される区切り文字が必要です。たとえば、次の入力を使用します。

42+24

getline_until()(strtok()またはのように) 上記をトークン、、およびgetline()に分割することはできません。42+24

于 2013-01-31T07:34:50.463 に答える