Парсинг строк в arduino
- Войдите на сайт для отправки комментариев
Чт, 07/06/2018 - 19:20
Есть вводная строка :
HTTP/1.1 200 OK
Date: Thu, 07 Jun 2018 15:18:23 GMT
Server: Apache/2.4.33 (Win32) OpenSSL/1.0.2n PHP/5.6.35
X-Powered-By: PHP/5.6.35
Content-Length: 39
Connection: close
Content-Type: text/html; charset=UTF-8
<html><body><h3>0/24</h3></body></html>;
Нужно получить число выделенное жирным.
Мой метод парсинга был просто перебиранием всего массива до момента пока я не найду слово '<h3>'. Может наши народные умельцы имеют более интересные решения?
Мой метод парсинга был просто перебиранием всего массива до момента пока я не найду слово '<h3>'.
Интересны методы других людей.
А если искать, то что после ">" но не "<"? И каковы пределы изменения искомого?
Имхо, самый простой алгоритмически вариант - это тупо
Всё.
1-2 cимвола
1-2 cимвола
"/24" постоянно присутствует?
да
Имхо, самый простой алгоритмически вариант - это тупо
Всё.
Если быстро не надо, то да
Если быстро не надо, то да
Т.е. просмотреть сотню-другую байтов при тактовой 16 МГц - это слишком медленно?
Нет, существуют методы, которые теоретически быстрее. Но - только теоретически, т.к. уменьшают количество операций сравнения, но при этом увеличивают накладные расходы на каждую операцию. Точнее, на длинных строках - можно получить заметный эффект, а на строке из 4-х символов много не наоптимизируешь.
Имхо, самый простой алгоритмически вариант - это тупо
Всё.
Если быстро не надо, то да
Предлагаете делением пополам искать? Овчинка выделки не стоит при таких объёмах входящих данных. Потом - всё зависит от реализации strstr - если она (а это, скорее всего, так) написана грамотно - то работает быстрее некуда и так уже.
Имхо, самый простой алгоритмически вариант - это тупо
Всё.
Если не трудно, переведите \ откомменнтируйте плиз этот код, как слабо знающий С нифига не понял
Бег указателем по буферу, пока не встретится '\0' или '/' с одновременным добавлением текущего символа к строке.
Правда, не понял зачем +4... это только для текущего примера с тэгом из четырех букв.
Имхо, самый простой алгоритмически вариант - это тупо
Всё.
Откомментировал.
Ещё вариант, в виде функции, возвращающей число, и без использования всяких String:
Писал навскидку, с учётом знака, только целые числа после нужной подстроки. Могут быть апшипки.
Имхо, самый простой алгоритмически вариант - это тупо
1
char
* ptr = strstr_P(buffer,(
const
char
*) F(
"<h3>"
));
2
if
(ptr)
3
{
4
ptr += 4;
5
String result;
6
while
(*ptr && *ptr !=
'/'
)
7
result += *ptr++;
8
}
Всё.
Имхо, самый простой алгоритмически вариант - это тупо
1
char
* ptr = strstr_P(buffer,(
const
char
*) F(
"<h3>"
));
2
if
(ptr)
3
{
4
ptr += 4;
5
String result;
6
while
(*ptr && *ptr !=
'/'
)
7
result += *ptr++;
8
}
Всё.
Если не писать чушь и посмотреть тип данных, в котором ищется, то сразу станет понятно, что char* ОБЯЗАНА заканчиваться нулём - это так принято в C/C++, поскольку нет встроенного типа данных "строка".
Для того, чтобы это понять - достаточно посмотреть прототип strstr, и тогда желание писать глупости - поубавится ;)
Если быстро не надо, то да
Т.е. просмотреть сотню-другую байтов при тактовой 16 МГц - это слишком медленно?
Нет, существуют методы, которые теоретически быстрее. Но - только теоретически, т.к. уменьшают количество операций сравнения, но при этом увеличивают накладные расходы на каждую операцию. Точнее, на длинных строках - можно получить заметный эффект, а на строке из 4-х символов много не наоптимизируешь.
чтобы говорить предметно надо открыть Вирта, написать код и посмотреть...
к примеру совершенно не вижу смысла просматривать заголовок, на вскидку там байт 100
есть еще функция trim, которой можно обрезать ненужные строки
Для того, чтобы это понять - достаточно посмотреть прототип strstr, и тогда желание писать глупости - поубавится ;)
Если писать не говнокод, а нормальную функцию поиска подстроки, имея буфер и длину, надо убедиться что это HTTP по первым 4 символам, найти Content-Length:, взять значение 39, найти /r/n/r/n и с этого места искать подстроку в 39 символах.
Для того, чтобы это понять - достаточно посмотреть прототип strstr, и тогда желание писать глупости - поубавится ;)
Если писать не говнокод, а нормальную функцию поиска подстроки, имея буфер и длину, надо убедиться что это HTTP по первым 4 символам, найти Content-Length:, взять значение 39, найти /r/n/r/n и с этого места искать подстроку в 39 символах.
нахрена??? поставить указатель на начало поиска зная указатель конца буфера можно простым вычитанием длины данных, здесь это значение равно 39, то-есть указатель начала блока данных равен указатель конца буфера минус 39
к примеру совершенно не вижу смысла просматривать заголовок, на вскидку там байт 100
Да, просматривать заголовок - это, конечно, совершенно лишнее.
Во только как определить, что он закончился, и пора начинать искать, собственно, данные?
нахрена??? поставить указатель на начало поиска зная указатель конца буфера можно простым вычитанием длины данных, здесь это значение равно 39, то-есть указатель начала блока данных равен указатель конца буфера минус 39
"Конца буфера" или "конца заполлненной части буфера"?
Если первое - откуда уверенность, что искомое находится не дельше 39 символа от него. А если второе - сколько операций нужно сделать, чтобы найти конец заполненной части буфера? А то ведь можеь оказаться, что вместо того, чтобы найти искомое в районе, скажем 80-го символа, мы сначала просматриваем буфер до 120 символа и только потом отнимаем 39. Т.е. вместо 80 операций делаем 120.
нахрена??? поставить указатель на начало поиска зная указатель конца буфера можно простым вычитанием длины данных, здесь это значение равно 39, то-есть указатель начала блока данных равен указатель конца буфера минус 39
"Конца буфера" или "конца заполлненной части буфера"?
Если первое - откуда уверенность, что искомое находится не дельше 39 символа от него. А если второе - сколько операций нужно сделать, чтобы найти конец заполненной части буфера? А то ведь можеь оказаться, что вместо того, чтобы найти искомое в районе, скажем 80-го символа, мы сначала просматриваем буфер до 120 символа и только потом отнимаем 39. Т.е. вместо 80 операций делаем 120.
адрес конца (дальнейшего начала буфера) у вас всегда должен быть, или написание кода предполагает какой-то особый способ работы с буфером?
адрес конца (дальнейшего начала буфера) у вас всегда должен быть
К сожалению, я не знаю, как следует реагировать на утверждение "всегда должен быть", т.к. не понял, Вы все-таки говорите о конце буфера либо о его начале.
Вот у нас есть буфер. Адрес его начала нам (компилятору) известен. Еслит известна длина буфера, адрес конца - тоже известен. Затем некоторая внешняя функция заполнила нам часть буфера. Должен ли нам быть известен адрес конца этой заполненной части, как Вы считаете?
Для того, чтобы это понять - достаточно посмотреть прототип strstr, и тогда желание писать глупости - поубавится ;)
Если писать не говнокод, а нормальную функцию поиска подстроки, имея буфер и длину, надо убедиться что это HTTP по первым 4 символам, найти Content-Length:, взять значение 39, найти /r/n/r/n и с этого места искать подстроку в 39 символах.
Ещё раз для упоротых: посмотри прототип strstr и уже успокойся - она работает с указателем на массив символов (char*), который ОБЯЗАН заканчиваться нулевым байтом. Если не заканчивается - программист, который передал в strstr чушь - такой же, как и ты: выскочка и недоучка, который ищет проблемы там, где их нет.
Товарищи-инжинеры. Я сделал костыль который даст мне большие приемущества упростив всем жизнь. Я просто написал скрипт на php который будет возвращать в сокет данные без всего. Только информация. Ибо добавить 1 файлик в сайт будет более оптимально с точки зрения нагрузки. Увеличит плавность подсветки.
Я конечно не супер программист, но за год с небольшим работы с ардуино попадал в ситуацию что выходил за пределы выделенного массива именно из за того что ноль в конце не прописывал при работе со строками, теперь поиск подстроки в строке пишу сам с учётом максимальной возможной длины строки
Да обе ситуации нормальны и имееют право на жизнь: та, в которой функция сама проверяет входные параметры и та, в которой она доверяет передающей функции. Первый способ безопасней, второй быстрее. Я где-то читал разбор кода линуксового ядра - там все на доверии построено, потому как контроль всех возможных ситуаций - это жуткий оверхед.
Да обе ситуации нормальны и имееют право на жизнь: та, в которой функция сама проверяет входные параметры и та, в которой она доверяет передающей функции. Первый способ безопасней, второй быстрее. Я где-то читал разбор кода линуксового ядра - там все на доверии построено, потому как контроль всех возможных ситуаций - это жуткий оверхед.
На мой взгляд, весма сомнительное утверждение.
Если бы оно было справедливо, Линукс бы валился от любого чиха неопытного программиста, не говоря уже о вирусах, написанных малограмотными школярами. Правильная программа должна корректно работать при любых входных данных, в том числе и некорректных (т.е. должна отслеживать корректность данных и в случае обнаружения некорректности обходить ее наименее разрушительным способом).
Речь не о программе, а о функции.
Или что, в линупсе strlen , к примеру, защиты имеет какие-то?
Речь не о программе, а о функции.
Или что, в линупсе strlen , к примеру, защиты имеет какие-то?
Ну, насколько мне известно, существуют и ее варианты с защитми (Си - не мой родной язык, так что напамять не воспроизведу).
Опять же, эта функция может использоваться в разных местах программы и обрабатывать различные данные. В зависимости от того, откуда берутся эти данные, можно применять разные варианты функций обработки строк "с" или "без" защит.
вспоминается мне большая "дыра" с этими strlen,strstr,strcmp когда передавали указатель на хитрую последовательность байт которая валила стек и получала управление в нужном месте.
но это было давно.
адрес конца (дальнейшего начала буфера) у вас всегда должен быть
К сожалению, я не знаю, как следует реагировать на утверждение "всегда должен быть", т.к. не понял, Вы все-таки говорите о конце буфера либо о его начале.
Вот у нас есть буфер. Адрес его начала нам (компилятору) известен. Еслит известна длина буфера, адрес конца - тоже известен. Затем некоторая внешняя функция заполнила нам часть буфера. Должен ли нам быть известен адрес конца этой заполненной части, как Вы считаете?
канэшна, адрес окончания блока данных в буфере известен всегда, или вы неправильно работаете с буфером
вспоминается мне большая "дыра" с этими strlen,strstr,strcmp когда передавали указатель на хитрую последовательность байт которая валила стек и получала управление в нужном месте.
но это было давно.
ну так это для архитектуры Intel где обрасть программ и данных пересекаются (одно и то же), на микроконтроллерах с риск архитектурой вроде как бы не должно )))
дата шит не читал, тряпками не бросать, если это не так, то буду сильно разочарован )))
Да обе ситуации нормальны и имееют право на жизнь: та, в которой функция сама проверяет входные параметры и та, в которой она доверяет передающей функции. Первый способ безопасней, второй быстрее. Я где-то читал разбор кода линуксового ядра - там все на доверии построено, потому как контроль всех возможных ситуаций - это жуткий оверхед.
Правильная программа должна корректно работать при любых входных данных, в том числе и некорректных (т.е. должна отслеживать корректность данных и в случае обнаружения некорректности обходить ее наименее разрушительным способом).
соглашусь 100% !!! Но студентов наших, усилиями коих пилятся сейчас все бюджетные деньги этому не учат, а вот в зарубежных фирмах разработков ПО это азбучная истина
Товарищи-инжинеры. Я сделал костыль который даст мне большие приемущества упростив всем жизнь. Я просто написал скрипт на php который будет возвращать в сокет данные без всего. Только информация. Ибо добавить 1 файлик в сайт будет более оптимально с точки зрения нагрузки. Увеличит плавность подсветки.
вот, жуткая полемика возымела действие, обработка перенесена на сторону сервера )))
Речь не о программе, а о функции.
Или что, в линупсе strlen , к примеру, защиты имеет какие-то?
Ну, насколько мне известно, существуют и ее варианты с защитми (Си - не мой родной язык, так что напамять не воспроизведу).
Опять же, эта функция может использоваться в разных местах программы и обрабатывать различные данные. В зависимости от того, откуда берутся эти данные, можно применять разные варианты функций обработки строк "с" или "без" защит.
И решение о использовании функции с защитой принимает кто? Правильно - программист. Он должен понимать значение и опасность вводимых данных, а не перекладывать решение на машину.
Достойно спроектированная же ОС не падает от проблем записи в userspace, а в kernel ring не допускает никого левого. Поделки же людей, которые заводят указатель неизвестно на что и пишут потом туда херню, шлепаются за милую душу. Но никто и не думает в связи с этим устраивать трагедию и анально огораживать все внутри маленького memmove, потому что смысла в этом нет.
Винда вон пускала в ранних версиях дрова в Ring 0 и что мы видели - постоянные синие экраны, как только юзер накатил странный драйвер. И ничего, разработчики винды не перестали пользоваться на нижнем уровне небезопасными функциями языка программирования, просто пересмотрели архитектуру.
Так ведь это ты передал в strstr чушь. Стало быть ты и есть "выскочка и недоучка".
Ой млять, совсем у тебя с головой не алё, видимо. Бывает.
И решение о использовании функции с защитой принимает кто? Правильно - программист. Он должен понимать значение и опасность вводимых данных, а не перекладывать решение на машину.
Ты только хомячкам местным малограмотным это не объясняй - бесполезно, эти тела всё с ног на голову поставят ;) Мало того, что не знают и не понимают простейших вещей, типа того - что такое псевдокод. Так и дальше - сморозит хуйню, и сидит с умным лицом, мол, смотрите какой я пушистый :)
Простейший пример многих заводит в тупик, с той же strstr: я что, должен носиться со всеми рукожопами и каждому вещать, что функция сия ждёт на вход буфера, заканчивающегося нулевым символом? И что если мамкин программист сунет туда херню - то понеслась?
Понимаешь масштаб бедствия у поколения ЕГЭ?
канэшна, адрес окончания блока данных в буфере известен всегда, или вы неправильно работаете с буфером
Тогда возникают следующие уточняющие вопросы:
1. Кому он известен?
2. Откуда он известен?
ну так это для архитектуры Intel где обрасть программ и данных пересекаются (одно и то же), на микроконтроллерах с риск архитектурой вроде как бы не должно )))
Аргументируйте.
Во-первых, вне зависимости от RISC/SISC на компьютерах с фон-неймановской архитектурой области программ и данных пересекаются по определению. Даже не просто пересекаются, а это - одна и та же область.
Во вторых, для гарвардской архитектуры, хотя инструкции и данные физически и разделены, логически они, как правило, находятся в общем адресном пространстве.
ну так это для архитектуры Intel где обрасть программ и данных пересекаются (одно и то же), на микроконтроллерах с риск архитектурой вроде как бы не должно )))
Аргументируйте.
Во-первых, вне зависимости от RISC/SISC на компьютерах с фон-неймановской архитектурой области программ и данных пересекаются по определению. Даже не просто пересекаются, а это - одна и та же область.
Во вторых, для гарвардской архитектуры, хотя инструкции и данные физически и разделены, логически они, как правило, находятся в общем адресном пространстве.
как ни крути крогом засада, а других архитектур нет?
я жеж ни разу не программист и электроника для меня хобби
Опять срач на ровном месте?
На мой взгляд, весма сомнительное утверждение.
... Правильная программа должна корректно работать при любых входных данных, в том числе и некорректных (т.е. должна отслеживать корректность данных и в случае обнаружения некорректности обходить ее наименее разрушительным способом).
Ваше первое предложение есть верный ответ на приведенную вашу же цитату.
Помнится, в году так 1990-м, участвовал в славном городе Севастополь на коференции по оптимизации ПО и разработке библиотек нижнего уровня (типа strstr). Помнится там велись жаркие дискуссии на предмет должна ли библиотечная функция контролировать и перепроверять все свои входные параметры .. помнится сильным аргументом стало что-то на предмет снижения общей производительности при вкладывании такой функции в цикл и особенно многократно. Там чуть ли не квадратичная зависимость потери производительности от количества проверяемых параметров, вариантов проверок и уровня вкладывания.
.. собственно после этого, наше поколение для идиотов придумало модель MVC .. дабы ВСЕ проверки выносились как можно выше и раньше.
Терпеть не могу когда мусорного кода для проверок ошибок в либах составляет половину библиотеки.
На мой взгляд, весма сомнительное утверждение.
... здесь была цитата
Ваше первое предложение есть верный ответ на приведенную вашу же цитату.
Аналогично. Вопрос обхода ошибки не может решаться силами библиотечных функций. Это задача вызывающего кода подавать правильные данные = правильно использовать библиотеку, а не "безмозгло".
ИМХО, это главная причина того, что многие тут в свое время не смогли пользовать тот самый arhat.h :)
ИМХО, это главная причина того, что многие тут в свое время не смогли пользовать тот самый arhat.h :)
да, нет, гдавная причина была в откровенных ляпах, которые автор упорно отказывался исправлять, доказывая всем. что это на самом деле фичи.
да, нет, гдавная причина была в откровенных ляпах, которые автор упорно отказывался исправлять, доказывая всем. что это на самом деле фичи.
Автору виднее.
Нет, мое представление о прекрасном тоже не совпадает с представлением автора arhat.h. Ну так я даже и не пытался использовать его библиотеку целиком: просмотрел, надергал полезных (с моей точки зрения) фрагментов, исправил места, где автор наделал откровенных (с моей точки зрения) ляпов, и с благодарностью к автору пользуюсь надерганным и исправленным.