![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Хочется сочетания простота + изящество + скорость + функциональность + безопасность.
Пример строки "param1=10, param2=2.0, param3=вася , ..." Чтобы зря мозг не парить. Вопрос прогулил. Что нашел. 1) stringstream - просто, быстро, безопасно, но не нифига не изящно и не функционально. Если извлечь как строку первый кусок, то это будет "param1=10," т.е. совсем не то что нужно. Значит нужно подключать find , потом перемещать позицию, потом вычислять длину текста "param1=" для того чтобы добавить к найденной позиции. Просто ужасно. 2) буст токинайзер. Ставлю разделитель знак "=", в результате получаю целую толпу токиенов. Среди них выделить нужные мне задача нетривиальная + не эффективность, поскольку создаются куча строковых переменных в куче из которых потом нужно получать значение. Само строковое представление токинов мне до лампочки. Итого функциональность + безопасность, остального нет. 3) буст regexp. встречал код разбивающий выражение на список токенов (list<>). Скорость еще ниже, еще больше "мусора", но результат лучше + чем токинайзер, но опять же конвертация типов ручная. Что имеем с sscanf - простота + изящество + скорость + функциональность. 4+, нет только безопасности. Неужели до сих пор нет приличного решения? Стока всего накрутили с бустами и STL ми, и тем не менее ничего красивее С так и не сделали? Кто что использует? Не хочется в новый проект закладывать небезопасный код. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| comcon1 |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 838 Регистрация: 11.6.2005 Где: Москва ДАС-МГУ Репутация: 12 Всего: 17 |
boost::regexp для разбора + boost::lexical_cast для конвертации
можно сделать хороший обработчик на базе boost::spirit с конвертацией и всеми делами, потому что сам спирит тяжел, но время компиляции - ### я использую первое для разбора мелочей, второе - для разбора файлов. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Интересно, но мой моск не осилил
Разыменовать одиночную круглую скобку с рядом стоящей строкой Непростой синтаксис Это сообщение отредактировал(а) Alexeis - 11.1.2010, 23:18 -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 8 Всего: 39 |
>"param1=10, param2=2.0, param3=вася , ..."
В данном примере написать распарсивалку в пять-десять строк - секундное дело. Будет дьявольски эффективно и безопасно. Когда мне лень писать пять строк, просто пользуюсь функцией для разбива строки на массив подстрок (аля пхпшный explode). Менее эффективно, безопасно, элементарно в использовании. -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| mes |
|
|||
|
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 144 Всего: 250 |
вообще то скобка не одиночная, а парная а * это не разъименователь, а перегруженный оператор. Добавлено через 3 минуты и 19 секунд Вы зря ленитесь спросить у гугля, зачастую это намного эффективней чем вопрос на форуме.. вот что дал гугл на первой же странице : http://blog.alno.name/2008/09/parsers-in-c...h-boost-spirit/ http://www.boost.org/doc/libs/1_32_0/libs/...c_concepts.html Добавлено через 6 минут и 21 секунду |
|||
|
||||
| Alexeis |
|
||||||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Но не изящно и не функционально. Когда стандартные вещи решаются стандартно это даже документировать не нужно. Ручной разбор негибок и не стоек к изменениям. Имеет плохую повторяемость в сходной ситуации. Добавлено через 5 минут и 14 секунд
Уже понял. Выглядит просто пугающе
Обычно так и делаю, но удачного решения так и не нагуглил -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
||||||
|
|||||||
| djamshud |
|
|||
![]() Пердупержденный ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1655 Регистрация: 23.11.2009 Репутация: 8 Всего: 39 |
Alexeis, не спорю. Но задача (на моей практике) редкая, да и комментарий
отлично это дело документирует). Это сообщение отредактировал(а) djamshud - 11.1.2010, 23:37 -------------------- 'Cuz I never walk away from what I know is right Alice Cooper - Freedom |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
mes, ссылка http://blog.alno.name/2008/09/parsers-in-c...h-boost-spirit/ в мемориз
Функционал отличный. Думаю, что для разбора простого синтаксиса идеальный вариант. Остается проверить производительность. Немного смущает коммент
Нужно будет еще рассмотреть вариант с AntLR. А так весьма неплохо. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 15 Всего: 88 |
юзай sscanf_s. Последняя s это и есть безопасность.. -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
| Alexeis |
|
|||
![]() Амеба Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 12 Всего: 459 |
Dov, обычно это _s защита от переполнения буфера, но никак не защита от того что я поменяю одну букву в формате и параметры более не будут соответствовать формату, что может привести к чему угодно. Приведу пример. В sscanf вместо указателя передается не инициализированная стековая переменная (типичная ошибка), значение переменной осталось от вызова другой функции где на этом месте был указатель на объект в куче. В результате значение адреса валидно, но функция sscanf неявным образом портит содержимое чужого объекта, не вызывая при этом AV. Реально мы видим странное поведение программы. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
| bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 63 Всего: 196 |
для парсинга (относительно) сложных конструкций использую boost::spirit. Да, компилируется долго, зато, когда набил руку, то парсер пишется быстро и в достаточно простых случаях - без серьезных ошибок. Читать ошибки, конечно, то еще удовольствие...
В твоем бы случае я бы использовал (да и использую) std::istringstream, std::transform, самописный класс Variant (хотя, возможно, boost::variant тебе подойдет) и функтор, который, собственно, разделяет левую и правую части от знака присваивания. |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |