LINUX.ORG.RU

Разбить строку на части по разделителю, на Си++


0

1

Нашел два хороших способа:

#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));
и
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    return split(s, delim, elems);
}

std::vector<std::string> x = split("one:two::three", ':');

Источник: http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c

Есть что-нибудь более компактное без boost?

★★★★★

Взять нормальный язык вместо крестов.

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

> strtok, можно один раз написать функцию и использовать ее

Точно ... я помню, что что-то такое в Си уже есть.

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

> А вообще, чем приведенное решение не компактно?

Через <string> - да, некомпактно. Хочется 2-3 строчек кода.

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

> QString Class Reference

Этот стиль программирования мне напоминает старый-добрый Borland Delphi.
Всё лаконично и аккуратно.

pacify ★★★★★
() автор топика

>Нашел два хороших способа:

boost

std::stringstream

Мне кажется, тебе стоит вернуться обратно к похапе. Из-за таких «прогромиздов» как ты появляются треды вроде Неужто все так быстро устаревает?

По существу: если уж так хочется извращаться на крестах, то

  std::string str = "127.0.0.1";
  std::vector<std::string> result;
  size_t pos = 0;
  while (1) {
    size_t end = str.find('.', pos);
    if (end == str.npos) {
      result.push_back(str.substr(pos));
      break;
    } else {
      result.push_back(str.substr(pos, end - pos));
      pos = end + 1;
    }
  }
red_eyed_peguin
()
Ответ на: комментарий от red_eyed_peguin

> Мне кажется, тебе стоит вернуться обратно к похапе.

Когда я начинал программировать, похапэ вроде как и не существовало.


Из-за таких «прогромиздов» как ты появляются треды вроде [тред про тормознутость винды]


))

Отчасти ты прав, двое моих знакомых из нашей школы работают в Редмонде, в компании Майкрософт, а третий был главным архитектором «Аллодов». Так что, не всё так печально. Конечно, ты поспешишь заверить меня, что учеба у одних и тех же преподавателей не означает того, что я нахожусь на уровне этих призеров международных олимпиад по информатике и математике. Но тут в полете фантазии я тебя ограничивать не буду.

Если коротко и по делу: я раньше (в студенческое время) писал такой же быдлокод, как и у тебя.

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

Хочется 2-3 строчек кода.

Одна строчка кода:

auto list = split(string, ':');
Какая разница что там внутри, покуда оно работает нормально?


Вот порт реализации из Qt:

std::vector<std::string> split(const std::string &string, char sep, bool keepEmptyParts = false) {
    std::vector<std::string> list;
    std::string::size_type start = 0;
    std::string::size_type end;
    while ((end = string.find(sep, start)) != std::string::npos) {
        if (start != end || keepEmptyParts)
            list.push_back(string.substr(start, end - start));
        start = end + 1;
    }
    if (start != string.size() || keepEmptyParts)
        list.push_back(string.substr(start));
    return list;
}

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

> strtok, можно один раз написать функцию и использовать ее

Хм-хм. А после вызова этой функции нужно долбить токены, пока те не закончатся? Получается, что strtok - не thread-safe?

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

>уровень призеров международных олимпиад по информатике и математике

Внимание, сейчас будет откровение: олимпиадники - весьма херовые разработчики сами по себе. Любят писать запутанный неподдерживаемый говнокод. Математика с программированием из общего имеют разве что символы «+-*/».

Если коротко и по делу: я раньше (в студенческое время) писал такой же быдлокод, как и у тебя.

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

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

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

red_eyed_peguin
()
Ответ на: комментарий от pacify

> Получается, что strtok - не thread-safe?

нет, для этого есть похожая функция strtok_r

aho
()
Ответ на: комментарий от rival

Я сделал очень просто:

        char *p;
        p = strtok(node17->value(), " "); std::cout << " " << p;
        p = strtok(0x00, " "); std::cout << " " << p;
        p = strtok(0x00, " "); std::cout << " " << p;
        p = strtok(0x00, " "); std::cout << " " << p;
        p = strtok(0x00, " "); std::cout << " " << p;
        std::cout << "\n";

вывод:

 8 14 4 3 -1.
 8 15 4 1 3.
 0 15 14 4 -1.
(собственно, надо было распарсить DATA-элементы из XML)

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

> Но ты можешь продолжать и дальше гордиться тем

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

aho:

нет, для этого есть похожая функция strtok_r


Ок, сенькс. Буду иметь ввиду.

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

>В чем недостаток stringstream?

Недостаток в том, что это тормозной плюсовый stream.

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

> Так. Стоп. Ты написал свой split на std::string. Чем ты теперь недоволен?

Я написал с использованием strtok() по совету aho.
А до этого интересовался, что лучше подходит для split.

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

уродство абстракций хочется сказать об этом коде эти жирные контейнеры генерируют тонны говна уродство синтаксиса это все можно назвать одним словом фуу

std::vector<std::string> split(const std::string &string, char sep, bool keepEmptyParts = false) {
    std::vector<std::string> list;
    std::string::size_type start = 0;
    std::string::size_type end;
    while ((end = string.find(sep, start)) != std::string::npos) {
        if (start != end || keepEmptyParts)
            list.push_back(string.substr(start, end - start));
        start = end + 1;
    }
    if (start != string.size() || keepEmptyParts)
        list.push_back(string.substr(start));
    return list;
}
лучше уж на яве или чем то больше высокоуровневом писать чем так писать на плюсах

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

А вот у микрософта в отличии от этого мерзкого stl есть отличный класс CString... По-моему наглядный пример, как можно нормально писать на плюсах. И наглядный пример для сравнения, где видно, когда код становится уродским, а когда нет.

CAtlString str(_T("%First Second#Third"));
CAtlString resToken;
int curPos = 0;

resToken= str.Tokenize(_T("% #"),curPos);
while (resToken != _T(""))
{
   _tprintf_s(_T("Resulting token: %s\n"), resToken);
   resToken = str.Tokenize(_T("% #"), curPos);
};   

http://msdn.microsoft.com/en-us/library/k4ftfkd2.aspx

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

Да, такокую крутотень точно не реализовать при помощи наследования std::string и домаблением метода, слава разработчикам МС, товарищи!

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

strtok зло, хоть у него и есть тред-сейф версия, то это всё равно не С++ стайл.

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

только вместо strtok надо использовать strtok_r

Reset ★★★★★
()

2, 3 строчки кода..

std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    for(std::string item; std::getline(ss, item, delim); ) elems.push_back(item);
    return elems;
}
anonymous2 ★★★★★
()
Ответ на: комментарий от anonymous2

Что уж там, почему бы не в одну строчку?

std::vector<std::string> &split(const std::string &s, char d, std::vector<std::string> &e) { std::stringstream ss(s); for(std::string i; getline(ss, i, d);) e.push_back(i); return e; }
Компактненько.

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

Ещё бы чуть-чуть и не влезло в мои 1920 :}

Deleted
()
Ответ на: комментарий от pacify

> Когда я начинал программировать, похапэ вроде как и не существовало.

зачем фотку внука на аватар прицепил?

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

>> Когда я начинал программировать, похапэ вроде как и не существовало.

Я начал программировать году в 89-90-м.

а этот пхп был создан через пять лет:

PHP was originally created by Rasmus Lerdorf in 1995.


зачем фотку внука на аватар прицепил?


не пью, не курю - вот и молодо выгляжу

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

> ТС так и не осилил libxml?

Я использовал libxml2 только в рамках модели SAX.
И где-то прочитал, что libxml2 был разработан в плане применения модели DOM только для Си, хотя и существуют врапперы к нему для Си++.

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

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

> Компактненько.

Мне эти шаманские бубны не объяснить людям, которые будут изучать мои алгоритмы по исходному коду. В данном случае, я стараюсь писать код, который понятен школьнику.

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