последовательность разделителей в функции strtok - PullRequest
1 голос
/ 16 ноября 2011

Я пытаюсь получить токены с функцией strtok() в C ++.Это очень просто, когда вы используете только 1 разделитель, например: token = strtok(auxiliar,"[,]");.Это обрезает auxiliar каждый раз, когда функция находит [, , или ].

Я хочу получить токены с последовательностью разделителей, например: [,] Это возможно сделать с помощью функции strtok?Я не могу найти путь.

Спасибо!

Ответы [ 4 ]

2 голосов
/ 16 ноября 2011

Если вы хотите, чтобы strtok рассматривал [,] как одиночный токен, это сделать невозможно. strtok всегда обрабатывает все, что вы передаете в строке разделителей, как отдельные 1-символьные разделители.

Помимо этого, лучше не использовать strtok в C ++. Это не повторный вход (например, вы не можете вкладывать вызовы), небезопасный и очень простой в использовании способ, который создает неприятные ошибки.

Самое простое решение - просто найти с помощью std::string нужного разделителя в цикле. Если вам нужна более сложная функциональность, в библиотеке Boost есть токены, и я также разместил код для более полного токенизации с использованием только стандартной библиотеки, здесь .

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

1 голос
/ 16 ноября 2011

Если это действительно C ++, вы должны использовать std :: string, а не строки C.

Вот пример, в котором используется только STL для разделения std::string на std::vector:

#include <cstddef>
#include <string>
#include <vector>

std::vector<std::string> split(std::string str, std::string sep) {
    std::vector<std::string> vec;

    size_t i = 0, j = 0;
    do {
        i = str.find(sep, j);
        vec.push_back( str.substr(j, i-j) );
        j = i + sep.size();
    } while (i != str.npos);

    return vec;
}

int main() {
    std::vector<std::string> vec = split("This[,]is[[,]your, string", "[,]");
    // vec is contains "This", "is[", "your, string"

    return 0;
}
0 голосов
/ 16 ноября 2011

Если вы можете использовать новые функции C ++ 11, вы можете сделать это с помощью итераторов регулярных выражений и токенов. Например:

regex reg("\[,\]");
const sregex_token_iterator end;
string aux(auxilar);
for(sregex_token_iterator iter(aux.begin(), aux.end(), reg); iter != end; ++iter) {
    cout << *iter << endl;
}

Этот пример взят из книги Wrox Professional C ++.

0 голосов
/ 16 ноября 2011

Если вы можете использовать библиотеку наддува, я думаю, что это будет делать то, что вы хотите, - не совсем уверен, хотя ваш вопрос немного неясен

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

#include <boost/tokenizer.hpp>

int main(int argc, char *argv[])
{
   std::string data("[this],[is],[some],[weird],[fields],[data],[I],[want],[to],[split]");

   boost::tokenizer<boost::char_separator<char> > tokens(data, boost::char_separator<char>("],["));

   std::vector<std::string> words(tokens.begin(), tokens.end());

   for(std::vector<std::string>::const_iterator i=words.begin(),end=words.end(); i!=end; ++i)
   {
      std::cout << '\'' << *i << "'\n";
   }
   return 0;
}

Это дает следующий вывод

'this'
'is'
'some'
'weird'
'fields'
'data'
'I'
'want'
'to'
'split'
...