2016-12-08 26 views
2

したがって、私はユーザーからの入力として任意に長い文字列を持っており、トークン化してvector<std::string>に格納したいと考えています。複数の区切り文字を使用した区切り

#include <iostream> 
#include <vector> 
#include <string> 
#include <iterator> 
#include <sstream> 
#include <string.h> 
using namespace std; 

int main() 
{ 
    string input; 
    cout << "Input a \' \' or \',\' or \'\\r\' separated string: "; 
    cin >> input; 

    vector<string> tokens; 

    char *str = new char[input.length() + 1]; 
    strcpy(str, input.c_str()); 
    char * pch; 
    pch = strtok(str, " , \r"); 
    while (pch != NULL) 
    { 
     tokens.push_back(pch); 
     pch = strtok(NULL, " , \r"); 
    } 

    for (vector<string>::const_iterator i = tokens.begin(); i != tokens.end(); ++i) 
     cout << *i << ' '; 
    return 0; 
} 

しかし、これが唯一のすなわちのように、その後の最初の単語と何をトークン化:

Input a ' ' or ',' or '\r' string: hello, world I am C. 
hello 

何午前ここで(多分私のCの背景からインスピレーションを得た)私が使用していたコードです私は間違っているし、サードパーティ製のライブラリを使用せずにそれを行う正しい方法は何ですか?よろしくです。 よろしくお願いします。

+0

あなたのトークン化と間違って何もありません。もう一度、対話的な入力を解析するためにこれらの人々に ''を使用するよう教えている人は、それらを混乱させるだけです。代わりに、 'std :: getline()'を使って1行の入力を読むように教えてください。最初の空白で止まる '>>'ではなく 'std :: getline()'を使うようにコードを変更してください。 –

+0

@SamVarshavchikうわー!それはうまくいった!それを記入する答えとしてこれを書いてください。 –

+1

@ Jeet.Deir 'char * str = new char [input.length()+ 1]; strcpy(str、input.c_str()); ' - 動的割り当てや' strcpy'の必要はありません。 'std :: vector ' - 'std :: vector str(input.begin()、input.end());を使います。 str.push_back(0); '。その後、 'strtok(str.data()、...)' – PaulMcKenzie

答えて

3

これは、悲しいことに、かなり一般的な落とし穴です。このような対話型の入力を受け付けるようにあなたを教える++ C上の多くの入門講座や書籍:

cin >> input; 

多くの入門簡単な演習では、典型的には、いくつかの並べ替えの単一の値の入力を要求し、それはそのユースケースのために、正常に動作します。

残念なことに、これらの書籍は実際には>>の内容を完全には説明していませんが、実際には入力から空白を取り除き、入力を処理して次の空白まで処理します。 inputが文字列であっても

したがって、テキスト行全体を入力すると、最初の単語だけがinputに読み込まれます。解決策は、右の仕事のための適切なツール、使用することです:std::getline()、テキストの一行を読み込み、単一文字列変数に格納します:

getline(cin, input); 
関連する問題