C ++ разделенная строка - PullRequest
       19

C ++ разделенная строка

4 голосов
/ 28 апреля 2010

Я пытаюсь разбить строку, используя пробелы в качестве разделителя. Я хотел бы хранить каждый токен в массиве или векторе.

Я пытался.

    string tempInput;
    cin >> tempInput;
    string input[5];

    stringstream ss(tempInput); // Insert the string into a stream
    int i=0;
    while (ss >> tempInput){
        input[i] = tempInput;
        i++;
    }

Проблема в том, что если я введу «это тест», то массив, похоже, будет хранить только input [0] = «this» Он не содержит значений для ввода [2] через input [4].

Я также пытался использовать вектор, но с тем же результатом.

Ответы [ 3 ]

5 голосов
/ 28 апреля 2010

Перейдите к дублирующимся вопросам, чтобы узнать, как разбить строку на слова, но ваш метод на самом деле правильный. Фактическая проблема заключается в том, как вы читаете ввод до , пытаясь его разбить:

string tempInput;
cin >> tempInput; // !!!

Когда вы используете cin >> tempInput, вы получаете только первое слово из ввода, а не весь текст. Есть два возможных пути выхода из этого, самый простой из которых - забыть о stringstream и напрямую повторять ввод:

std::string tempInput;
std::vector< std::string > tokens;
while ( std::cin >> tempInput ) {
   tokens.push_back( tempInput );
}
// alternatively, including algorithm and iterator headers:
std::vector< std::string > tokens;
std::copy( std::istream_iterator<std::string>( std::cin ),
           std::istream_iterator<std::string>(),
           std::back_inserter(tokens) );

Этот подход даст вам все токены на входе в одном векторе. Если вам нужно работать с каждой строкой отдельно, вам следует использовать getline из заголовка <string> вместо cin >> tempInput:

std::string tempInput;
while ( getline( std::cin, tempInput ) ) { // read line
   // tokenize the line, possibly with your own code or 
   // any answer in the 'duplicate' question
}
3 голосов
/ 28 апреля 2010

Обратите внимание, что гораздо проще просто использовать copy:

vector<string> tokens;
copy(istream_iterator<string>(cin),
     istream_iterator<string>(),
     back_inserter(tokens));

Что касается того, почему ваш код не работает: вы повторно используете tempInput. Не делай этого. Кроме того, вы сначала читаете одно слово из cin, , а не всей строки. Вот почему в stringstream.

помещается только одно слово.
1 голос
/ 28 апреля 2010

Самый простой способ: Boost.Tokenizer

std::vector<std::string> tokens;

std::string s = "This is,  a test";
boost::tokenizer<> tok(s);
for(boost::tokenizer<>::iterator it=tok.begin(); it != tok.end(); ++it)
{
  tokens.push_back(*it);
}

// tokens is ["This", "is", "a", "test"]

Вы можете задать параметры разделителей и escape-последовательностей так, чтобы они занимали только пробелы, если хотите, по умолчанию он разделяется на пробелы и знаки препинания.

...