Парсим POST запрос
- Войдите на сайт для отправки комментариев
пытаюсь разобраться с веб интерфейсами и передачей данных на sd карту
нашел занятные примеры с использованием ajax но пока что не делаю, иду по упрощенному варианту...возникла следующая проблема, подскажите над каким решением подумать можно??
http://startingelect...lly-using-AJAX/
по этой ссылке читается POST запрос и сохраняется в переменную таким образом
if (client.available()) { // client data available to read char c = client.read(); // read 1 byte (character) from client HTTP_req += c; // save the HTTP request 1 char at a time
тут все понятно, я стал делать свой пример, у меня все данные передаются все хорошо и получается что я принимаю в эту переменную строку вида
r2=on&r3=on&r4=on&postTemp=123
где rN - это мои релешки которые я включаю через веб интерфейс, а postTemp - это значение температуры пороговое при котором я тыркаю какую то релешку, оно у меня устанавливается на странице текстбоксом
так вот когда я получил строку такого вида как ее распрарсить??
Причем строка может как вида полного когда все реле включены и температура не задана
r2=on&r3=on&r4=on&postTemp=
так и когда все реле выключены и ничего не задано
postTemp=
или когда задана температура но реле выключены
postTemp=123
как это лучше всего парсить?
я брал пример просто без порогового значения отсюда...там парсится чисто по символьно
http://zelectro.cc/E...et_shield_W5100
но для моей задачи теперь считаю что этот подход не верный - мне проще собрать сначала всю строку запроса а потом ее парсить и изменять массив состояния реле
strtok() спасет гиганта мысли :)
1. считать всю строку зараз
2. разбить на куски с разделителем &
3. каждый кусок разбить с разделителем =
это, как говорится, "в лоб".
возможно, есть какие-нибудь готовые сишные библиотеки, но тут делов на десяток строчек
http://arduino.ru/forum/programmirovanie/razbor-testovoi-stroki#comment-...
Точнее даже 24 пост той темы что я выше кинул, там уже кое что поправили и дефайны вынесли для определения разделителей
Спасибо, на самом деле уже нашел ту ссылку что вы кинули..но у меня немного иная задача, я пошел по другому пути...
У меня для начала строка формируется POST методом
Читаю я ее в String
а теперь когда получаю нужную мне строку из post запроса, то буду ее парсить..нашел либу по регуляркам не плохую, думаю ей воспользоваться, потому как у меня будет 3х уровневый разбор
http://forum.arduino.cc/index.php/topic,59917.html
у меня строка вида
r0=on&r1=on&r3=on&postTemp=100500
следовательно надо сопоставить номера релюх и внести изменения в массив состояния реле соответствующее номеру текущего реле + выдернуть значение порога температуры в отдельную переменную...либо же просто распарсить без порога или без релюх
Еще отдельно актуален вопрос...
Я заношу запрос в строку типа String..не хочется пользоваться типом, много жрет места...но когда я определяю указатель на char то у меня в Serial ничего не выводит...я так понимаю потому как указатель на char висит тупо в памяти, а мне видимо надо создать еще массив указателей и его выводить или я ошибаюсь?
Я заношу запрос в строку типа String..не хочется пользоваться типом, много жрет места...но когда я определяю указатель на char то у меня в Serial ничего не выводит...я так понимаю потому как указатель на char висит тупо в памяти, а мне видимо надо создать еще массив указателей и его выводить или я ошибаюсь?
тупо он висит или не тупо - без кода не определить
Я заношу запрос в строку типа String..не хочется пользоваться типом, много жрет места...но когда я определяю указатель на char то у меня в Serial ничего не выводит...я так понимаю потому как указатель на char висит тупо в памяти, а мне видимо надо создать еще массив указателей и его выводить или я ошибаюсь?
тупо он висит или не тупо - без кода не определить
вот тестовый код
но когда пишу
все работает.
String - это строка. Ну, то есть, настроящая текстовая строка, из разных буковок и циферок.
char* - это указатель на одну из таких буковок - отдельную, или в составе какой-то строки - это сейчас не важно. Но прибавлять буквы к указателю - бессмысленно. Прибавлять надо к тому, на что он указывает.
String - это строка. Ну, то есть, настроящая текстовая строка, из разных буковок и циферок.
char* - это указатель на одну из таких буковок - отдельную, или в составе какой-то строки - это сейчас не важно. Но прибавлять буквы к указателю - бессмысленно. Прибавлять надо к тому, на что он указывает.
так вот как разщ если я наприаер пишу такое
у меня фактически это как раз указатель на набор символов, так?
могу ли я к этому набору прибавить новый символ считанный...у меня же сейчас char указывает на то что в кавычках или нет?
char* ch = "werhweifjweilf ifjsifj ofjsroifj op";
у меня фактически это как раз указатель на набор символов, так?
Точно, так. Сейчас ch - это стрелочка указывающая на начало строки. А саму строку компилятор положил в память, куда-то там, куда ему захотелось.
могу ли я к этому набору прибавить новый символ считанный...у меня же сейчас char указывает на то что в кавычках или нет?
Да, можешь, но с поправками.
Во-первых, компилятор выделил память только под то, что написано в кавычках. Добавлять что-то в конец нельзя - залезешь в чужую память. А в пределах этой строки - пожалуйста, можно затирать любые символы и писать на их место другие.
Во-вторых, для такого типа компилятор не знает операции "+", поэтому записывать придётся вручную, так же как в любую другую переменную.
Записывать можно двумя способами. Можно оставить указатель на месте, а нужный символ строки выбирать с помощью индекса в скобках.
А можно двигать сам указатель.
Обычно, то же самое пишут попроще - запись значения и сдвиг указателя сразу, одной строкой:
При такой "ручной" записи всегда надо следить, чтобы случайно не вылезти за пределы выделенной строки.
При использовании типа String компилятор следит за этим сам, и если буфера не хватает, он выделит другой, побольше, и скопирует строку в него. Конечно, это дольше, и занимает больше памяти под код, и наверно под данные тоже. Но программировать так проще, и если запас по памяти и по скорости есть - пожалуйста, почему бы и не String.
-------
Upd: А, ещё. Лучше выделять буфер с указанием необходимого размера.
Только, при таком объявлении, ch это уже не указатель, а имя массива. В общем, пользоваться можно почти так же, но разница в том, что его не получится никуда сдвинуть. Это не страшно - если хочется двигать, можно создать указатель-копию.
Во, целую лекцию написал. Надеюсь, всё понятно. Я старался. :)
да, спасибо за подробное объяснение...пожалуй остановлюсь на простом типе String, т.к. у меня заранее не известно какой длинны будет строка POST запроса, она может динамически меняться, поэтому если я выделю 10 символов под размер буфера то памяти может не хватить...да и пока еще трудно понимаю тему указателей. года 3 назад начинал ее активно учить двигаться, погрузился и так и не доперли сложнее вещи.
Нужны какие то лекции с простым объяснением указателей и массивов указателей (** или *** и т.д)
Начал разбираться, почитал форум библиотеки регулярных выражений, возникли сразу вопросы, кое что не получается...
1 - у меня на входе строка типа String, начал писать функцию парсинга строки с использованием библы
2 - при использовании библиотеки на вход нужен указатель на строку символов, начал конвертировать String в char* и тут проблема я не допонимаю немного в чем именно трудность
как раз у меня проблема в конвертации chararray в char* почему явно не могу сказать указателю, что вот моя строка символов?
и еще с самой регуляркой вопрос
моя строка вида
r0=on&r1=on&postTemp=123
регулярка ее разберет из примера с форума вот так
"(%a+)(%d)=(%-?%a+)"
тут как я понял читаем сначала произвольное кол-во символов, далее идет цифра, все как у меня, потом =, а что дальше?? у меня может быть как on значение так и типа float (температура)....следовательно вот тут %-?%a+ читается только символы (прочитается on) а у меня помимо on может быть и значение температуры...
и еще так и не понял что значит -?
http://forum.arduino.cc/index.php?topic=59917.15
пост номер 5
На выходе получите:
Я тогда не пойму в чем моя ошибка??
почему такая конструкция не работает?
UPD:
у нас же
Вы во второй строке преобразуете rStr в массив, в а 3й строке в качестве аргумента передаете опять же rStr, а надо преобразованный массив. И sizeof тут работать не будет, вы получите размер указателя а не размер строки, надо length использовать.
Нет, bufferReqStr используется только при обработке регулярных выражений (GetMath, GetCapture) в этот буфер складываются результаты сравнений грубо говоря. А в bufferStr лежит наша преобразованная строка (из String в chararray)
Вы во второй строке преобразуете rStr в массив, в а 3й строке в качестве аргумента передаете опять же rStr, а надо преобразованный массив. И sizeof тут работать не будет, вы получите размер указателя а не размер строки, надо length использовать.
не понимаю одну вещь все равно
я попробовал ваш вариант, все работает
почему я не могу использовать везде содин буфер?
Нет, bufferReqStr используется только при обработке регулярных выражений (GetMath, GetCapture) в этот буфер складываются результаты сравнений грубо говоря. А в bufferStr лежит наша преобразованная строка (из String в chararray)
понял теперь...выходит во время выполнения они оба используются и содержат разные данные.
спасибо.
А вообще видимо надо почитать много чего про char, потому как до этого я думал что создавая массив
char bufferReqStr[reqStr.length() + 1]; у меня просто создастся массив размера моей строки, оказывается сама строка копируется в этот массив с учетом ее размера...до этого я считал что он содержит непонятные данные под которые выделяется память указанного размера.
Ну если вкратце, то они затрут друг друга. И мы не получим желаемого результата
Всё правильно, char bufferReqStr[reqStr.length() + 1]; не копирует строку, он просто выделяет указанное количество памяти и всё. А "копирование" происходит при вызове toCharArray
Всё правильно, char bufferReqStr[reqStr.length() + 1]; не копирует строку, он просто выделяет указанное количество памяти и всё. А "копирование" происходит при вызове toCharArray
Разобрался теперь...сначала мы веделяем 2 буффера - один для хранения символов нашей строки - как раз при преобразовании копируем строку в него, указанного размера строки, второй - это просто буффер для работы в самом цикле, для промежуточных операций регулярок.
Да, именно так.
Благодарю! Шикарно теперь можно парсить строки сложные, вроде понял!
(%a+)(%d-)=([%a%d]+)
Только почему d- ??
Я так понимаю a+ учитывает что может быть множество символов
d определяет число именно, но почему "-"???
И опять же d только работает я потестил с целочисленными данными
Если задать порог с плавающей точкой, то получаем округленное значение.
Ну - это значит 0 или более вхождений нежадное. т.е. после r есть цифра, а после postTemp нет, вот поэтому 0 или более. Да работает только пока разделитель не встретится в виде точки или запятой для дробных, поэтому надо немного переписать и добавить в квадратные скобки точку. Сейчас на работе времени нет, вечером дома гляну как там лучше переписать регулярку.
Вот так можно написать, тогда будет парсить и целые числа и с плавающей точкой где разделитель . (точка)
(%a+)(%d-)=([%a%d\.]+)
Вот так можно написать, тогда будет парсить и целые числа и с плавающей точкой где разделитель . (точка)
(%a+)(%d-)=([%a%d\.]+)
благодарю, попробую!
Не хочу сбивать с толку, но может, если нужно удалённое управление, сгодится вариант облачного сервиса?
Тогда ничего парсить не придётся, сайт сам сгенерирует исходный код программы.
Останется только вставить свой полезный код в каждый из обработчиков.
И крапеть над визуальными интерфейсами не потребуется, воспользуетесь готовыми компонентами.
Реально, всю работу можно будет сделать в течении нескольких минут.
Если заинтересуетесь, но что-то будет непонятно, то я помогу.
http://samde.ru/ru/index.html