Как токенизировать строку по разделителям?

Мне нужно токенизировать строку разделителями.

Например:

За "One, Two Three,,, Four" мне нужно получить {"One", "Two", "Three", "Four"},

Я пытаюсь использовать это решение https://stackoverflow.com/a/55680/1034253

std::vector<std::string> strToArray(const std::string &str,
const std::string &delimiters = " ,")
{
boost::char_separator<char> sep(delimiters.c_str());
boost::tokenizer<boost::char_separator<char>> tokens(str.c_str(), sep);

std::vector<std::string> result;
for (const auto &token: tokens) {
result.push_back(token);
}

return result;
}

Но я получаю ошибку:

boost-1_57 \ boost / tokenizer.hpp (62): ошибка C2228: слева от .begin должен быть класс / структура / объединение
тип «const char * const»

0

Решение

Изменить это:

boost::tokenizer<boost::char_separator<char>> tokens(str.c_str(), sep);

К этому:

boost::tokenizer<boost::char_separator<char>> tokens(str, sep);

Ссылка на сайт:
http://www.boost.org/doc/libs/1_57_0/libs/tokenizer/tokenizer.htm

Тип контейнера требует begin() функция и const char * (что к чему c_str()) возврат не соответствует этому требованию.

2

Другие решения

Токенизатор Boost, вероятно, излишний для задачи, которую вы описываете.

boost::split был написан для этой конкретной задачи.

std::vector<std::string> strToArray(const std::string &str,
const std::string &delimiters = " ,")
{
using namespace boost;
std::vector<std::string> result;
split( result, str, is_any_of(delimiters), token_compress_on );
return result;
}

Это необязательно token_compress_on означает, что ваш ,,, вход не должен подразумевать пустые строки токенов между этими запятыми.

1

Короткий путь.

string tmp = "One, Two, Tree, Four";
int pos = 0;
while (pos = tmp.find(", ") and pos > 0){
string s = tmp.substr(0, pos);
tmp = tmp.substr(pos+2);
cout << s;
}
1

Я вижу много boost ответы, поэтому я думал, что я поставлю неboost ответ:

template <typename OutputIter>
void Str2Arr( const std::string &str, const std::string &delim, int start, bool ignoreEmpty, OutputIter iter )
{
int pos = str.find_first_of( delim, start );
if (pos != std::string::npos) {
std::string nStr = str.substr( start, pos - start );
trim( nStr );

if (!nStr.empty() || !ignoreEmpty)
*iter++ = nStr;
Str2Arr( str, delim, pos + 1, ignoreEmpty, iter );
}
else
{
std::string nStr = str.substr( start, str.length() - start );
trim( nStr );

if (!nStr.empty() || !ignoreEmpty)
*iter++ = nStr;
}
}

std::vector<std::string> Str2Arr( const std::string &str, const std::string &delim )
{
std::vector<std::string> result;
Str2Arr( str, delim, 0, true, std::back_inserter( result ) );
return std::move( result );
}

trim может быть любая функция обрезки, я использовал этот так ответ. Это использует std::back_inserter и рекурсия. Вы можете легко сделать это в цикле, но это звучит как веселее 🙂

0
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector