Разбор строки
- Войдите на сайт для отправки комментариев
Для одного своего проекта потребовалось разобрать строку.
Строка содержит следущие сущности:
- команда (строка, вообще говоря, произвольной длинны) - обязательный параметр
- идентификатор блока (строка, 3 символа) - обязательный параметр
- номер функции (число, пока от 0 до 9, но лучше - произвольное) - не обязательный параметр
- данные (число, пока от 0 до 9, но лучше - произвольное) - не обязательный параметр
Строку на передающей стороне собираю нормально... теперь проблема - разобрать ее нормально на принимающей стороне.
Пока заработал вот такой скетчик:
#include <string.h>
char unitID_in[10];
int devID_in;
char command_in[10];
char data_in[100];
void setup() {
// открываем порт
Serial.begin(9600);
}
void loop() {
int i=0;
char buffer[100];
//если есть данные - читаем
if(Serial.available()){
delay(100);
//загоняем прочитанное в буфер
while( Serial.available() && i< 99) {
buffer[i++] = Serial.read();
}
//закрываем массив
buffer[i++]='\0';
}
//если буфер наполнен
if(i>0){
//разбераем его на части отделенные запятой
sscanf(buffer, "%[^','],%[^','],%[^','],%s", &command_in, &unitID_in, &devID_in, &data_in);
}
if ((String)unitID_in == "001"){
Serial.print("command: ");
Serial.print(command_in);
Serial.print("\n");
Serial.print("unit: ");
Serial.print(unitID_in);
Serial.print("\n");
Serial.print("dev: ");
Serial.print(devID_in-48);
Serial.print("\n");
Serial.print("data: ");
Serial.print(data_in);
Serial.print("\n");
unitID_in [0] = '\0';
command_in [0] = '\0';
devID_in = 0;
data_in [0] = '\0';
}
}
В этом скетче сначала все параметры входящие были строками (нормально работает, но нужны и целочисленные значения). Попробовал это сделать для параметра devID_in (см.строку 47 - какой-то некрасивый хак получился, особенно, когда данные для этого параметра отсутствуют).
Как строку разобрать лучше? Или, может, вообще как-то иначе работать со строкой?
Строка на передающей стороне получается примерно следующего вида: set,001,4,8
Сам смешу - сам смеюсь :)
Разобрался с функцией sscanf.
пришлось переделать строку, которую дуина принимает (разделители должны быть пробелами (еще поддерживаются табуляторы)). Параллельно еще упростил свою систему (стало достаточно трех параметров в команде).
Дальше все просто:
params = sscanf(buffer, "%s%s%d", &command, &unitID, &attr);Дополнительно получено значение params - количество принятых параметров в строке.
Такие "умные" сишные функции - благо... пока хватает памяти. Потом наступает стадия оптимизация, приходится часто отказываться от "умных" функцый.
AlexFisher, а как быть в этом случае?
Анализировать входящую строку посимвольно, преобразовывать в числа более "легкими" функциями, часто не библиотечными. Посмотрите тему про перевод принятой строки в число
Вообще, общих советов нет. В ряде случаев победить библиотечную функцию вообще не удается.
А как получить параметры? тоесть обратиться например к строке
Serial.print(data_in);
она не выводит ничего
Поделитесь плиз, как правильно разбирать строки в порту, в том числе разделенные запятыми??
пример выше мне понравился, но почему он не силно правильный для ардуины?
Приведите примеры как выэто делаете, заране всем спасибо.
Что значит "в порту"?
в компорту....
кстати, в тему ветки, пример из интернета:
http://bigbarrel.ru/arduino_serial_example/
как указать вместо 1T - переод строки? тоесть у меня строка может быть разной длинны, и нужно указать что перед знаком перевода строки остановить считывание.
Начните вот с этого поста и до конца темы смотрите, там ещё пример есть. Принцип у всех примеров один и тот же - любой разюорщик - конечный автомат. Примеры реализации там есть.