разбор строки по разделителю

sergeyksv45
Offline
Зарегистрирован: 24.02.2016

Приветствую!!! Прошу помощи!

Столкнулся с проблемой при разборе строки. собираю теплицу

*******
gprs.readSMS(message, phone);        // читаю сообщение и номер отправителя
    delay(300);
    gprs.deleteSMS(messageIndex);        // удаляю смс
    delay(300);

    char * text = message;               // текстовое сообщение в массив 
    char * part1 = text;                       // первая часть до разделителя ":"
    char * part2 = strchr(text, ':');      // вторая часть  после разделителя до конца строки
    *part2++ = '\0';

Вот часть кода. В нем всё раскладывается на две части норм 

Например приходит сообщение "Poliv:20" далее в первой части "Poliv" а во второй части "20" т.е длительность полива, а вот как разбить сообщение "Poliv:18.15" для настройки и записи времени полива, теперь надо разбить на три части 1 - "Poliv" 2 - "18" 3 - "15", а как это сделать не могу

okta
Offline
Зарегистрирован: 10.01.2015

1е действие - разбить на две части

2е действие - взять вторую часть и повторить действие первое

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Пропробовал потому как удивился что part1 выводит "Poliv". Хотя явно указано что "part1 = text" а "text = message" а message у нас равен "Poliv:18.15". Ну и непонятно почему нельзя сразу  "part1  message", результат будет тот же.

void setup() {
    Serial.begin(9600);
    char message[] = "Poliv:18.15";

    char * text = message;               // текстовое сообщение в массив 
    char * part1 = text;                       // первая часть до разделителя ":"
    char * part2 = strchr(text, ':');      // вторая часть  после разделителя до конца строки
    *part2++ = '\0';
  
    Serial.println(message);
    Serial.println(text);
    Serial.println(part1);
    Serial.println(part2);
}

void loop() {
}

выводит это

Poliv
Poliv
Poliv
18.15

То есть : это какойто волшебный разделитель для char?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Только что давал коллеге пример подобного разбора. Посмотрите в посте №2 - http://arduino.ru/forum/programmirovanie/eshche-raz-pro-strtok

sergeyksv45
Offline
Зарегистрирован: 24.02.2016
gprs.readSMS(message, phone);        // читаю сообщение и номер отправителя
    delay(300);
    gprs.deleteSMS(messageIndex);        // удаляю смс
    delay(300);

    char * text = message;
    char * part1 = text;
    char * part2 = strchr(text, ':');
    *part2++ = '\0';

    Serial.print("Part 1: ");
    Serial.println(part1);
    Serial.print("Part 2: ");
    Serial.println(part2);

у меня выводит это

1256 24.31 mode:1 poliv:28 poliv1:0
Part 1: Poliv
Part 2: 15
Poliv: 15
 1260 24.31 mode:1 poliv:15 poliv1:0

в сериал порт при входящем смс "poliv:15" всё раскладывается и далее присваиваю переменной значение 15 и записываю в память контроллера, так что тут без волшебства всё ОК!

1 строка со старым значением 28, 4 строка присваиваю значение 15, 5 строка проверяю (обновилось ли)

получилось сделать!!!может и не так презентабельно)

*************
gprs.readSMS(message, phone);        // читаю сообщение и номер отправителя
    delay(300);
    gprs.deleteSMS(messageIndex);        // удаляю смс
    delay(300);

    char * text = message;
    char * part1 = text;
    char * part2 = strchr(text, ':');
    *part2++ = '\0';
    char * part = part2;
    char * part3 = strchr(part2, '.');
    *part3++ = '\0';

    Serial.print("Part 1: ");
    Serial.println(part1);
    Serial.print("Part 2: ");
    Serial.println(part2);
    Serial.print("Part 3: ");
    Serial.println(part3);
************

при входящем смс тексте "Poliv:15"

расклад

Part 1: Poliv
Part 2: 15
Part 3: 

при входящем смс тексте "Time_poliv:17.34"

расклад

Part 1: Time_poliv
Part 2: 17
Part 3: 34

 

axill
Offline
Зарегистрирован: 05.09.2011

для такой задачи больше подходит функция strtok

первый раз вызываем ее указывая первый разделитель, второй раз второй

обратите внимание, что второй и последующий разы вместо строки надо передавать NULL, функция внутри сама помнит указатель на следующую часть текста

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

Да я попробовал через strtok, работает. В принципе можно массив параметров сделать а не отдельные переменные, и в цикле тогда разбирать строку.

void setup() {
      Serial.begin(115200);
      char *message = "Poliv:18.15";
  
      char * params = strtok (message,":.");
      char * part1 = params;
      params = strtok (NULL, ":.");
      char * part2 = params;
      params = strtok (NULL, ":.");
      char * part3 = params;
  
      Serial.println(part1);
      Serial.println(part2);
      Serial.println(part3);
}

void loop() {
}

 

sergeyksv45
Offline
Зарегистрирован: 24.02.2016

Да работает!!! Отправляю "Time:17.34" в порту расклад

Time
17
34

проверено в железе и работает, спасибо! Теперь можно усложнить задачу разбора строки, попробую в строке - "время(RTC) установить, продолжительность полива (в ручном режиме), продолжительность полива при определенной влажности почвы в авторежиме - их 3, время полива в авто режиме, температура отрывания форточек, температура закрывания форточек. Отправлять настройки дуньке буду через андроид приложение посредством смс сообщений.