Russian Qt Forum

Qt => Общие вопросы => Тема начата: Igors от Декабрь 06, 2011, 15:53



Название: QString iterator
Отправлено: Igors от Декабрь 06, 2011, 15:53
Добрый день

Недавно (для отладки) потребовалось сортировать такие строки (по ключу "x")
Цитировать
color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.
Конечно сделал, но хотелось бы "удобств". В данном случае можно просто найти "х =", ну так это "только данный случай" :) Будет напр "x=" (без пробелов) или неск таких - и опять придется суетиться.

Про RegExp ничего не знаю. Наверное если люди его придумали он зачем-то нужен, но так ли уж обязательно сразу "тащить корову на баню"? А вот было бы интересно иметь итератор который пробегает строку "токен за токеном", напр
Код
C++ (Qt)
QStringIterator it(theStr);
while (it.hasNext()) {
qDebug() << *it;
++it;
}
 
Для строки выше
Цитировать
color
=
(
1.34
,
0.21
...
Все остальное я бы легко накрутил. Есть ли такой класс?

Спасибо


Название: Re: QString iterator
Отправлено: Aluman от Декабрь 06, 2011, 16:07
На сколько я знаю нет, возможно стоит посмотреть метод QString::split, что-то подобное он позволяет сделать.


Название: Re: QString iterator
Отправлено: Igors от Декабрь 06, 2011, 16:14
На сколько я знаю нет, возможно стоит посмотреть метод QString::split, что-то подобное он позволяет сделать.
Схожу-ка я лучше в магазин - нет сил разговаривать с такой бескрылой молодежью  :'(


Название: Re: QString iterator
Отправлено: kambala от Декабрь 06, 2011, 17:34
Про RegExp ничего не знаю. Наверное если люди его придумали он зачем-то нужен, но так ли уж обязательно сразу "тащить корову на баню"?
если не изобретать особо изощрённые велосипеды, то тащить корову нужно. но нужно знать все возможные форматы строки (если они такие, как указаны в первом посте, не считая пустых символов, то написать регэксп легко).


Название: Re: QString iterator
Отправлено: Igors от Декабрь 06, 2011, 19:26
если не изобретать особо изощрённые велосипеды, то тащить корову нужно. но нужно знать все возможные форматы строки (если они такие, как указаны в первом посте, не считая пустых символов, то написать регэксп легко).
А "грамотная бескрылость" - еще хуже  :)


Название: Re: QString iterator
Отправлено: SimpleSunny от Декабрь 06, 2011, 19:31
А чем таки split не угодил?


Название: Re: QString iterator
Отправлено: Пантер от Декабрь 06, 2011, 19:53
Код
C++ (Qt)
foreach (consr QString &it, string.split (' ')) {
 
}
 
Что тут не нравится?


Название: Re: QString iterator
Отправлено: kambala от Декабрь 06, 2011, 20:01
если не изобретать особо изощрённые велосипеды, то тащить корову нужно. но нужно знать все возможные форматы строки (если они такие, как указаны в первом посте, не считая пустых символов, то написать регэксп легко).
А "грамотная бескрылость" - еще хуже  :)
не всегда нужно лезть в самые истоки. конечно, если очень важна производительность (ага, для вывода отладочных сообщений), то надо свой "узкоспециализированный" парсер писать.

а ещё кстати strtok() есть.
Код
C++ (Qt)
foreach (consr QString &it, string.split (' ')) {
 
}
 
Что тут не нравится?
тут запятая/скобка будут приписаны к числу, а не являться отдельным элементом.


Название: Re: QString iterator
Отправлено: Пантер от Декабрь 06, 2011, 20:04
тут запятая/скобка будут приписаны к числу, а не являться отдельным элементом.
Этого не заметил. Тогда сплитать простым регекспом. Можно еще в сторону буста глянуть.


Название: Re: QString iterator
Отправлено: BRE от Декабрь 06, 2011, 20:10
Есть ли такой класс?
КонЭчно Эсть, точнее набор классов объединенных в boost.spirit :)
Но там много C++.


Название: Re: QString iterator
Отправлено: vregess от Декабрь 07, 2011, 13:31
Я бы начал с регулярок. Если дело пойдет дальше, и надо будет делать что-то более оптимизированное по скорости и возможностям, то копать в сторону boost.spirit и всякие antlr/lex/flex/bison.

Я не спец по таким штукам, но если я понял правильно задачу:
Код:
    QString str = "color = (1.34, 0.21, 0.2,12),  x = 1.23e-5f,. ";
    QRegExp rx("(\\w+|[+-]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+f)?|[=\\(\\)])");

    int i = 0;
    while((i = rx.indexIn(str, i)) != -1)
    {
        qDebug() << rx.cap(1);
        i += rx.matchedLength();
    }

Выводит:
Код:
color
=
(
1.34
0.21
0.2
12
)
x
=
1.23e-5f
Регэксп выглядит ужасно, но все не так страшно

Выражение:
Код:
"(\\w+|[+-]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+f)?|[=\\(\\)])"

оно же без экранирующей фигни
Код:
(\w+|[+-]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+f)?|[=\(\)])

по составным частям
Код:
(
  \w+             // числобуква 1 или более повторений = идентификатор
  |                 // оператор или
  [+-]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+f)?  // число с плавающей точкой, разные вариации: 11, .0, +11.3232e+12f и тд
  |                 // оператор или
  [=\(\)]         // набор разных операторов (можно дополнить): = ( )
)


Название: Re: QString iterator
Отправлено: Igors от Декабрь 07, 2011, 19:48
А чем таки split не угодил?
Та нервирует он меня ужасно  :'(  Ну как это так, вызвать сотни, (может тысячи) malloc без надобности? Ладно, допустим это мои проблемы. Но ведь он и не делает что нужно - разделитель безобразно фиксирован. Чего так глупо лезть с QStringList? Как правило нужно взять первый токен и по нему смотреть - может пропустить до конца строки, может до определенного токена. Имея итератор получить list - не вопрос

КонЭчно Эсть, точнее набор классов объединенных в boost.spirit :)
Но там много C++.
Ой напугали :) Но здесь разговор о QString. Понятно что есть др. средства, но за их использование придется платить "переливаниями". Конечно хочется делать все однообразно.

а ещё кстати strtok() есть.
Та хоть бы аналог strtok дали для QString !! Но я его в упор не вижу (буду только рад если ошибся, "ткните носиком"). Да, есть section, можно искать "по словам", но оно все раздроблено, никак не взаимодействует  :'( 

kambala, я немного погорячился в своем предыдущем посте, извините.

Я бы начал с регулярок. Если дело пойдет дальше, и надо будет делать что-то более оптимизированное по скорости и возможностям, то копать в сторону boost.spirit и всякие antlr/lex/flex/bison.

Я не спец по таким штукам, но если я понял правильно задачу:
Я Вас понял, спасибо. Конечно, не так страшен черт как его малюют, и с QRegExp разобраться можно (в конце-концов прочитать Third Edition как советует букварь). Беда в том что мне придется заставлять это делать других (я не один работаю над проектом) - и этого очень хотелось бы избежать.

Ну что такого уж "страшно-невозможного" я хочу? У меня нет никакого желания тягаться с (Q)RegExp, пусть он будет в 100 раз мощнее. Но для конкретных нужд простенький (lite) тул был бы куда полезнее. Вот все сидят в каком-то редакторе для программистов (я даже не знаю в каком). Просто наберите напр

1.45e-5f,
MyClass.MyMethod()

Теперь double-clicck на 1.45.. Подсветится все исключая финальную запятую. На MyClass - тогда до точки. То есть выбирается "токен". Конечно это можно сделать (и делается) руками, но где это в Qt? Почему такой реально нужной вещи нет и приходится лезть в дебри и/или ковыряться по символам?

Спасибо


Название: Re: QString iterator
Отправлено: BRE от Декабрь 07, 2011, 19:54
Теперь double-clicck на 1.45.. Подсветится все исключая финальную запятую.
Черт, а у меня 45e выделяет или 1.

На MyClass - тогда до точки.
А с этим справился. :)

А если серьезно, то "токен" должен выделяется по какому то правилу известному только тебе. Это правило ты должен как-то описать... например, с помощью regexp или spirit'а или lex/bison или ...


Название: Re: QString iterator
Отправлено: Igors от Декабрь 07, 2011, 20:45
А если серьезно, то "токен" должен выделяется по какому то правилу известному только тебе. Это правило ты должен как-то описать... например, с помощью regexp или spirit'а или lex/bison или ...
Та неужели только мне? :)  А так
Код
C++ (Qt)
QString str("1.45e-5");
bool Ok = false;
float f = str.toFloat(&Ok);
 
почему я здесь ничего не должен? Или даже так
Код
C++ (Qt)
char * c_ctr = "1.45e-5f";
char * endP;
float d = strtod(c_ctr, &endP);
 
Я ведь не прошу чтобы мне автоматычно делали float/double. Дайте токен, дальше я разберусь


Название: Re: QString iterator
Отправлено: BRE от Декабрь 07, 2011, 20:50
Я ведь не прошу чтобы мне автоматычно делали float/double. Дайте токен, дальше я разберусь
Ага-ага.
А почему в строке:
Цитировать
color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.
ты считаешь отдельным токеном color или x? Может здесь отдельный токен - "color = (" или "x = 1."?
А как "волшебный" метод в QString должен до этого догадаться? :)




Название: Re: QString iterator
Отправлено: Igors от Декабрь 07, 2011, 21:00
Ага, завелись :) Я отвечу, но давайте "не частить", пусть и другие скажут, а то получается личная перепалка (как уже бывало). Ok?  :)


Название: Re: QString iterator
Отправлено: BRE от Декабрь 07, 2011, 21:12
...перепалка...
Перепалка?
Не видал ты наверное перепалок на лоре. :)


Название: Re: QString iterator
Отправлено: Igors от Декабрь 07, 2011, 21:24
Перепалка?
Не видал ты наверное перепалок на лоре. :)
Я вырос в большой коммунальной квартире. Когда я стал "немного" старше я понял что просто не стоит терять время на пустые базары типа "кто круче". Говорим по делу/теме, Ok? (понты просто неинтересны)


Название: Re: QString iterator
Отправлено: BRE от Декабрь 07, 2011, 21:27
Говорим по делу/теме, Ok? (понты просто неинтересны)
Эээ странное заявление, а я где то говорил не по делу? Да и с понтами на твоем фоне я просто блекну. :)


Название: Re: QString iterator
Отправлено: andrew.k от Декабрь 07, 2011, 22:03
А почему ты так не хочешь с регэкспами разобраться? На это нужно не больше дня с нуля.
Чтобы простенькие писать и час достаточно.
Столько же времени потребуется каждому члену твоей команды.
Ну пару дней. Регэкспы целиком решают твою задачу.


Название: Re: QString iterator
Отправлено: vregess от Декабрь 07, 2011, 23:14
Цитировать
Беда в том что мне придется заставлять это делать других (я не один работаю над проектом) - и этого очень хотелось бы избежать.

Ну что такого уж "страшно-невозможного" я хочу? У меня нет никакого желания тягаться с (Q)RegExp, пусть он будет в 100 раз мощнее. Но для конкретных нужд простенький (lite) тул был бы куда полезнее.

Ну раз работает группа людей, и нужен lite tool и ваще все лень, то вот пожалуйста: http://goo.gl/xsTRq (http://goo.gl/xsTRq)
Тот же самый регэксп обернутый в класс + несколько полезных методов.
Теперь можно и так:
Код:
    RxTokenizer tk("color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.");

    while(tk.hasNext())
        qDebug() << tk.nextToken();

//     "color" "=" "(" "1.34" "0.21" "0.2" ")" "x" "=" "1.23e-5f"

и вот так
Код:
    RxTokenizer tk("color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.  ");
    tk.addToken(",\\.");

    while(tk.hasNext())
        qDebug()<< tk.nextToken();

//     "color" "=" "(" "1.34" "0.21" "0.2" ")" "x" "=" "1.23e-5f" ",."

и даже вот так
Код:
    RxTokenizer tk;
    tk.setTokens("\\w+");
    tk.setString("color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.  ");

    while(tk.hasNext())
        qDebug()<< tk.nextToken();

    // "color" "1" "34" "0" "21" "0" "2" "x" "1" "23e" "5f"


    tk.setString("color red green,blue");
    while(tk.hasNext())
        qDebug()<< tk.nextToken();

    // "color" "red" "green" "blue"


Кстати, неплохой класс вырисовывается, может у себя применю.

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


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 00:47
Ну раз работает группа людей, и нужен lite tool и ваще все лень, то вот пожалуйста: http://goo.gl/xsTRq (http://goo.gl/xsTRq)
Не стоит раздражаться, ленивых и халявщиков у нас нет. Сейчас разбор сделан на простом С - это имеет свои плюсы и минусы. Разумеется, та "задача" что я привел - это так, просто для примера. Она не выдумана, но текстовики попадаются очень разные, это всего лишь простейший случай. Мозгуем как лучше подойти "ваще"  :) Если Вы умеете (немного) читать между строк - наверное Вы поняли что речь (последовательный доступ) идет о файле (потоке, stream).


Название: Re: QString iterator
Отправлено: vregess от Декабрь 08, 2011, 12:27
Не стоит раздражаться, ленивых и халявщиков у нас нет.
нууу я бы сказал, это ирония вперемешку с сарказмом.

Сейчас разбор сделан на простом С - это имеет свои плюсы и минусы. Разумеется, та "задача" что я привел - это так, просто для примера. Она не выдумана, но текстовики попадаются очень разные, это всего лишь простейший случай. Мозгуем как лучше подойти "ваще"  :) Если Вы умеете (немного) читать между строк - наверное Вы поняли что речь (последовательный доступ) идет о файле (потоке, stream).
К сожалению я оказался плохим телепатом.

Ну и по делу.
regex не устраивает, хорошо.
Боюсь предложить, но возможно все-таки boost.spirit?
Хотя нет. Пробуем другой вариант сперва - boost.tokenizer:

Код:
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>

int main(int argc, char **argv)
{
    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
    std::string str = "color = (1.34, 0.21, 0.2),  x = 1.23e-5f,.";

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

    tokenizer::iterator it = tokens.begin();
    for(; it != tokens.end(); ++it)
       std::cout << "<" << *it << "> ";
    std::cout << std::endl;

    return 1;
}
// <color> <=> <(> <1.34> <0.21> <0.2> <)> <x> <=> <1.23e-5f> <.>

Не совсем то (<.> возможно не нужна), но это лишь направление.
Ну и нужно будет с собой таскать чать заголовков буста, но это решается при помощи bcp.
Кстати, будет интересно узнать, на чем все-таки остановишься.

И опять не по делу. Может оставим ненужный официоз, если Вы не против?


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 13:34
И опять не по делу. Может оставим ненужный официоз, если Вы не против?
Не обращайте внимания. Мне лично удобнее говорить с незнакомым человеком на Вы, говорите как Вам удобнее, нет проблем. Никакой иронии нет, наоборот, Ваши посты мне нравятся.

Контекст: проект реально большой, писался в разное время разными людьми. Почти каждому приходилось разбирать текстовик. Конечно каждый программист использовал свое, то что он лучше знает - это нормально. Это здесь "пригрелись" :)  а у нас - половина на char *, вторая на std::string, и кто-то еще с юникодом щемится. Вот и думаем как бы поудобнее. Переделать сразу тонны кода - не получится, да и не нужно (работает - ото нехай работает). но по крайней мере каждый новый разбор начинать не с нуля (увы, сейчас это так).

Перетерли, мнения конечно разные. Все понимают что нет "волшебной палочки", писать специфику так или иначе придется. Все сошлись на одном: базовый класс должен предоставлять возможность читать "токен за токеном", дальше крутить легко.

Понятие "токен" определено давно, и я лично никогда не слышал чтобы хоть что-нибудь изменилось. Грубо/приближенно

- это число? (обратите внимание что возможны спецификаторы, напр 12L, 256UL, 88LL, 5.43f)
- это "альфа"?  (space/tab)
- это буква или цифра?

Если все "нет" тогда это токен - единичный символ, напр =, запятая и.т.п. Возникают сложности с национальными алфавитами (получал по рогам с "немецкими кавычками"). Вот и хочется присесть на устойчивый "сервис" - а там уж RegExp или дуст (кстати классная вещь) или еще что - дело техники, на то есть вумное слово "инкапсуляция"  :)


Название: Re: QString iterator
Отправлено: andrew.k от Декабрь 08, 2011, 13:44
И опять не по делу. Может оставим ненужный официоз, если Вы не против?
Не обращайте внимания. Мне лично удобнее говорить с незнакомым человеком на Вы, говорите как Вам удобнее, нет проблем.
Форум это анонимная среда, поэтому "Вы" выглядит странно.
С 12 летними детьми ты тоже на Вы? А возраст оппонентов почти всегда неизвестен.

Поэтому когда 40-летний дядя пишет "Вы  вот то да се" 16-летнему, а тот ему в ответ, "да ты, да вот это".
Это не добавляет совершенно никакой "вежливости" к сообщениям.

Использование "Вы" на форуме имеет скорее противоположное действие.

Мое имхо. Пантер будет ругаться?


Название: Re: QString iterator
Отправлено: Пантер от Декабрь 08, 2011, 14:00
andrew.k, Bepec, рассадить бы вас по разным разделам форума. :D Кончайте флудить или буду сам удалять посты с оффтопом - не обижайтесь тогда.


Название: Re: QString iterator
Отправлено: vregess от Декабрь 08, 2011, 14:26
Цитировать
по теме:
Специалисты, вопрос. Если написать на Qt dll, а затем попытаться её использовать скажем в С++ чистом проекте, так прокатит?

Вопрос со строками меня тоже интересовал  Пришлось даже свой класс написать, который парсит С++ код и причем довольно успешно.

Это вопрос, причем по теме. Есть мысль создать первую свою dll'ку. Соответственно жду ответа :)


Задай себе вопрос, чем dll на Qt отличается от dll не на Qt. Правильный ответ - ничем, значит в общем случае она будет работать в чистом с++ проекте.
Тебе лишь нужно таскать с собой зависимости, ну и надо предусмотреть различного рода инициализации, например, если нужна обработка очереди сообщений.

И да, вопрос не по теме, тк тема "QString iterator".


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 14:48
Поэтому когда 40-летний дядя пишет "Вы  вот то да се" 16-летнему, а тот ему в ответ, "да ты, да вот это".
А вот пусть это борзое щеня и подумает "в своей ли оно тарелке" :) Хотя конечно есть и такие кто впитал хамство с молоком <template> матери и здесь уж ничего не попишешь

Специалисты, вопрос. Если написать на Qt dll, а затем попытаться её использовать скажем в С++ чистом проекте, так прокатит?
Формально да, практически - редко, потому что почти наверняка Qt dll будет рассчитывать на вход/выход "в стиле Qt"

Вопрос со строками меня тоже интересовал  Пришлось даже свой класс написать, который парсит С++ код и причем довольно успешно.
Ну и чего Вы застеснялись? Выкладывайте, обсудим. Не обращайте внимания на (так называемых) знатоков (мол, да все уже известно и за нас придумано) - это дешевые понты, не более того


Название: Re: QString iterator
Отправлено: BRE от Декабрь 08, 2011, 14:56
Формально да, практически - редко, потому что почти наверняка Qt dll будет рассчитывать на вход/выход "в стиле Qt"
Можно подробней про вход/выход "в стиле Qt". Спасибо.


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 15:21
Можно подробней про вход/выход "в стиле Qt". Спасибо.
Что значит это "Спасибо" от Вас ?????? Нездоровы... разводитесь с женой.. запили.. Я теряюсь в догадках  :)
Вопрос тоже странный. Конечно Qt dll будет рассчитывать на все имеющиеся Qt классы - и предполагать что хост тоже. Ну и там песня как импортировать классы и.т.п. Конечно такое будет работать
Код
C++ (Qt)
MY_EXPORT void DoSomething( const char * in, char * out );
 
Но оно неэффекитвно. Наверное я не понял вопроса


Название: Re: QString iterator
Отправлено: andrew.k от Декабрь 08, 2011, 15:28
Чтобы Пантер не нервничал, я создал отдельную тему (http://www.prog.org.ru/topic_20295_0.html)


Название: Re: QString iterator
Отправлено: BRE от Декабрь 08, 2011, 15:36
Вопрос тоже странный.
А что странного в вопросе? :)
Просто хотелось бы узнать что означает фраза "наверняка Qt dll будет рассчитывать на вход/выход "в стиле Qt". Что это за вход/выход?

Конечно Qt dll будет рассчитывать на все имеющиеся Qt классы
Почему Qt dll (а что такое Qt dll - QtCore.dll?) будет рассчитывать на все имеющиеся классы?  Сейчас Qt разделена на несколько разделяемых библиотек с четкими зависимостями - вот модуль Core вообще не зависит от других разделяемых библиотек Qt.

Ну и там песня как импортировать классы и.т.п.
Что это за песня такая?
Я тебе раскрою тайну - в dll нет классов и не может быть, там есть только функции и данные (класс это понятие абстрактное про которое знаешь ты и компилятор). Поэтому песен "как импортировать класс" просто не может быть. :)

Наверное я не понял вопроса
IMHO, целой темы.


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 20:12
Я тебе раскрою тайну - ...
Да не надо - жизнь слишком коротка чтобы тратить ее на бессмысленные познания  :)


Название: Re: QString iterator
Отправлено: BRE от Декабрь 08, 2011, 20:18
Да не надо - жизнь слишком коротка чтобы тратить ее на бессмысленные познания  :)
А рассуждать с важным видом на темы, про которые ты особо ничего не знаешь, имеет больше смысла?


Название: Re: QString iterator
Отправлено: Igors от Декабрь 08, 2011, 20:22
А рассуждать с важным видом на темы, про которые ты особо ничего не знаешь, имеет больше смысла?
Проигнорировано