Разбор строки с помощью strtok или sscanf и присвоение полученных значений переменным

IgorKa
Offline
Зарегистрирован: 06.11.2016

Помогите разобрать приходящие по serial-у строки на подстроки и присвоить полученные значения неким переменным для дальнейше обработки.

В serial приходят строки вида

XXXXX:   '\t'     yy.y   '\t'     zz.z

 где XXXX: - буквы, уу.у и zz.z - числа (могут быть целочисленными или с плавающей запятой),  значения разделены символами табуляции.

Мне нужно разобрать эти строки и присвоить полученные значения переменным, например a=XXXX: b=yy.y c=zz.z С помощью strtok получилось это сделать

char *pch;
pch = strtok (buffer,"\t");
 while (pch != NULL)
  {
   mySerial.println(pch);
    pch = strtok (NULL, "\t");

  delay(10);}

но как присвоить значения переменным незнаю. Вычитал что умные люди делают это с помощью sscanf, но опять же поскольку я себя пока к таковым не отношу сделать ничего не получается. Поэтому прошу помощи - подскажите каким образом это сделать или дайте хотя бы ссылку на полноценные примеры.

IgorKa
Offline
Зарегистрирован: 06.11.2016

да, забыл сказать что делал разбор также с помощью substring, но этот вариант тоже не подходит, т.к. приходящие значения время от времени могут быть разной длины и соответственно будут искажаться.

spa-sam
Offline
Зарегистрирован: 14.12.2012

Ищи по форуму, этот вопрос уже разбирался, я там тоже приводил в пример два метода.

IgorKa
Offline
Зарегистрирован: 06.11.2016

Естественно что перед тем как задать вопрос перелопатил форум. Из всего что удалось найти или не подходит к моим хотелкам или так и осталось неотвеченным.

Nosferatu
Offline
Зарегистрирован: 04.11.2012

Вот стандартные функции для ардуино из которых можно собрать парсер данных пришедших по serial.

IgorKa
Offline
Зарегистрирован: 06.11.2016

Ну и какую из этих функций применить чтобы из принятой строки

XXXX:  yy.y  zz.z

получить a=XXXX: b=yy.y c=zz.z ?

Nosferatu
Offline
Зарегистрирован: 04.11.2012

IgorKa пишет:

Ну и какую из этих функций применить чтобы из принятой строки

XXXX:  yy.y  zz.z

получить a=XXXX: b=yy.y c=zz.z ?

Например вот так:

String a;
float  b;
float  c;

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (Serial.available() > 0) {
    a = Serial.readStringUntil('  ');
    Serial.print("a = ");
    Serial.println(a);
    b = Serial.parseFloat();
    Serial.print("b = ");
    Serial.println(b);
    c = Serial.parseFloat();
    Serial.print("c = ");
    Serial.println(c);
  }
}

Переменная String конечно много памяти кушает, если что используйте readBytesUntil() например.

IgorKa
Offline
Зарегистрирован: 06.11.2016

Увы, но этот вариант мне не подходит. Строки из интересующей меня информации я собираю несколько иначе. Я уже смирился с "задержками", главное что получаю то что мне нужно. Осталось только разбить строки на подстроки и обработать их дальше. Кстати пробовал собирать строки с помощью Serial.readStringUnti() и Serial.readBytesUntil() - вообще ничего не получилось. Думал использовать что-то типа

sscanf(buffer, "{здесь должно быть каое-то форматирование}", &a,&b,&c);

но не знаю как правильно указать форматирование в скобках

Нигде не могу найти примеров sscanf чтобы все было разжевано на пальцах

uni
uni аватар
Offline
Зарегистрирован: 24.09.2015

На просторах сети когда-то достал такую функцию, попробуйте её доработать под свои нужды:

int dtmsplit(char *str, const char *delim, char ***array, int *length ) 
{
    int i=0;
    char *token;
    char **res = (char **) malloc(0 * sizeof(char *));

    /* get the first token */
    token = strtok(str, delim);

    while( token != NULL ) 
    {
        res = (char **) realloc(res, (i + 1) * sizeof(char *));
        res[i] = token;
        i++;
        token = strtok(NULL, delim);
    }

    *array = res;
    *length = i;

    return 1;
}

 

IgorKa
Offline
Зарегистрирован: 06.11.2016

uni пишет:

На просторах сети когда-то достал такую функцию, попробуйте её доработать под свои нужды:

Спасибо конечно, но я тут кагбэ со тсандартной "простой" функцией разобраться не могу, а вы мне предлагаете адаптировать написанную кем-то и еще без всяких пояснений. Мне бы че-нить попроще, а то я "смотрю в книгу и вижу фигу"

IgorKa
Offline
Зарегистрирован: 06.11.2016

Итак, прошерстив найденные примеры и используя метод научного тыка добился кое-каких результатов

sscanf(buffer, "%[^\t]\t%[^\t]\t%[^\t]", &a, &b, &c);

К надфилю переходить конечно рановато, но сменить рашпиль на напильник думаю уже можно