LINUX.ORG.RU

[C++] Разделение строки

 


0

1

Как без лишних заморочек разбить строку по разделителю произвольной длины? Как, например, в Python:

>>> "a=1<sep>b=2<sep>c=3".split("<sep>")
['a=1', 'b=2', 'c=3']
Что ближе всего к такому в C++? Есть в boost что-то для этого (кроме spirit)?


Ответ на: комментарий от najar

Обязательно нужно по разделителю произвольной длины. И желательно всё же, чтобы это было что-то готовое. От самописных вещей я как раз и хотел избавиться.

undet
() автор топика

Напиши функцию типа этой:

vector<string> split (string str, string sep=" ") {
    int idx = 0, lidx = 0, 
    sep_len = sep.size();
    vector<string> ret_list;

    while (true) {
        lidx = str.find(sep, idx);

        ret_list.push_back( str.substr(idx, lidx-idx) ); 

        if (lidx == string::npos)
            break;

        idx = lidx + sep.size();
    }  

    return ret_list;
}

И используй в проекте... з.ы. Хочешь краткости и ясности? пиши на python'е и не парься :)

anonymous
()

В Qt есть QString у которого есть метод split, который с точностью до синтаксиса делает то что ты сказал.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

ага... чувак пишет себе какой то проект... тут ему «умники» предлагают затащить мегобиблиотеку (пусть даже толко QtCore) для сплита строк.. Да вам на Java писать с таким подходом нужно, сударь :)

anonymous
()
Ответ на: комментарий от KblCb

Блин, я не понимаю... Boost - в первом посте. Какой такой QString?
Да и нафиг пользовать boost? Какие-то дикие библиотеки...
strtok - это не модно? При желании, возможно допилить string. :-\

a_n
()
Ответ на: комментарий от KblCb

> метод split, который с точностью до синтаксиса делает то что ты сказал.
А, понял. Извиняюсь. Это идеальный вариант: превращаем C++ в питон, превращаем C++ в паскаль, превращаем C++ в гопичный русский.

a_n
()
Ответ на: комментарий от anonymous

Хочешь краткости и ясности? пиши на python'е и не парься :)

Я бы с удовольствием, но проект почему-то на C++ (принято так, похоже, всё писать на C++). И да, меня мягко говоря не поймут, если я вдруг начну зависеть от Qt :). Самописные вещи вроде этой есть, но я их стараюсь заменять на готовое из того же boost'а. Подумал, а нет ли какого-нибудь boost'ового заклинания, чтобы и это тоже делало.

undet
() автор топика
Ответ на: комментарий от undet

Только что нашёл в boost алгоритм split. Интересно, почему: 1) это сделал я а не ты 2) он не возвращает контейнер списка, а требует передавать этот самый контейнер себе по ссылке.

KblCb ★★★★★
()
Ответ на: комментарий от anonymous

Чувак хочет чтобы всё было как в питоне. Как в питоне это когда ты тащишь в проект мегабиблиотеку, потом к ней же мегабиндинг и потом радуешься до усрачки, что самому писать ничего не пришлось. На самом деле человек как-то очень туманно сформулировал вопрос (типа «хочу чтоб у меня всё было») и я не обратил внимания, что он уже затащил в проект мегабиблиотеку, но другую. Честно говоря ему было бы легче если бы это был QtCore.

KblCb ★★★★★
()
Ответ на: комментарий от Gvidon

То есть предлагается превратить std::string в char*, чтобы порезать её сишной функцией, которая: а) потребует организацию цикла (не то что бы меня это пугает, но как-то расходится с реквестом в топике, не находите?); б) вернёт char*; в) память для char'ов выделит в куче malloc'ом? Плохая идея.

KblCb ★★★★★
()
Ответ на: комментарий от KblCb

Это который из String Algo что ли? 1) Я его тоже нашёл, но пока не понял как им делить не по отдельным символам, а по строкам. А вообще подходит. 2) Откуда я знаю? По мне, так это разумно.

undet
() автор топика
Ответ на: комментарий от undet

Хм, действительно. Забыл об этой её особенности. Но кажется мне автор на ожидание ответа на ЛОРе потратил уже гораздо больше времени, чем требуется на написание такой функции руками.

Gvidon ★★★★
()
Ответ на: комментарий от Gvidon

Должен повторить, что у меня всё есть, всё работает. Я просто ищу лучший вариант. Чтобы, как минимум, знать о нём, и использовать в следующий раз. Я не прошу предоставить мне какие-то решения или реализации.

undet
() автор топика
Ответ на: комментарий от JackyTreehorn
string s( "a=1<sep>b=2<sep>c=3<sep>s=4<sep>e=5<sep>p=6" ); 
   tokenizer< char_separator<char> > tok( s, char_separator<char>("<sep>") ); 
   copy( tok.begin(), tok.end(), ostream_iterator< string >( cout, "\n" ) );

Вывод:

a=1
b=2
c=3
=4
=5
=6
Будет работать правильно, если вместо char_separator написать свою TokenizerFunction.

undet
() автор топика
Ответ на: комментарий от kitov

Если не сложно, можешь показать как с ним правильно работать? Чтобы из строки «a=1<sep>b=2<sep>c=3<sep>s=4<sep>e=5<sep>p=6» получить «a=1», «b=2», «c=3», «s=4», «e=5» и «p=6».

undet
() автор топика
Ответ на: комментарий от KblCb

>тащишь в проект мегабиблиотеку, потом к ней же мегабиндинг и потом радуешься до усрачки, что самому писать ничего не пришлось.

Кто-то сказал «делфи»? Потому что мне послышалось, что кто-то сказал «делфи»!

legolegs ★★★★★
()
Ответ на: комментарий от legolegs

А… Ну да, ещё ты радуешься тому что не надо выписывать сигнатуры функций и следить за типами. Прошу прощения что ввёл в заблуждение.

KblCb ★★★★★
()
Ответ на: комментарий от one_more_hokum

>> Есть в boost что-то для этого (кроме spirit)?

Xpressive в частности, и регэкспы в общем?


Плюсую и подтверждаю.

JackYF ★★★★
()
Ответ на: комментарий от KblCb

c_str() не? Или это какой-то новый C++ в котором уже нет char?

a_n
()
Ответ на: комментарий от KblCb

> Jedem das seine
Кажется, это уже где-то писали? Я ж не против. Говорю - согласен.
Jedem das seine.
:-\

a_n
()
Ответ на: комментарий от KblCb

> а) потребует организацию цикла (не то что бы меня это пугает, но как-то расходится с реквестом в топике, не находите?);
И? Как вариант - допилить string, используя эту функцию. Как её допиливать - это уже дело вкуса. И привкуса. :-\

б) вернёт char*;

И что?

в) память для char'ов выделит в куче malloc'ом? Плохая идея.

Ну разве что. Так запилить в string и освободить, если так хочется.
Вообще, действительно, проще свою написать.
В чём проблема?

a_n
()
Ответ на: комментарий от undet

> strtok изменяет то, что ему дают как аргумент. Поэтому давать ему вывод c_str() нельзя.
Указатель? Так что мешает завести дополнительный и его передавать функции?

a_n
()
Ответ на: комментарий от undet

Блин, в любом случае, придётся что-то писать. Это простейшая задача. Как уже тут писали: в частности - любое решение, в общем- регэкспы.

a_n
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.