Arduino split char * на основе разделителя для значения - PullRequest
0 голосов
/ 22 марта 2020

спасибо за ваше время, поэтому у меня есть Char * от mqtt

Я хочу разбить это на 3 отдельных значения

Char* mqttvalue
//Input Would be like the below for example. 
mqttvalue = (255,200,230);

// I would like to split the values into the below.
int 1 = 255
int 2 = 200
int 3 = 230

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

Спасибо

Отредактируйте, что я пытался.

//Dummy Value for testing 
Split("255,240,230");

//Split Value
void Split(char*  e) {
  String v[3];
  char *p;
  int i = 0;
  p = strtok(e, ",");
  while(p && i < 3)
  {
    v[i] = p;
     p = strtok(NULL, ",");
     Serial.println(p);
     ++i;
  };
  Serial.println(v[0]);
  Serial.println(v[1]);
  Serial.println(v[2]);
}

Ответы [ 2 ]

0 голосов
/ 23 марта 2020

Поскольку это довольно часто задаваемый вопрос, я бы предложил больше использовать класс-оболочку, наследующий Потоковый интерфейс в строке C (и он также может быть инициализирован из объекта Arduino String).

Однако использование с классом Arduino String довольно сложно, так как исходная строка не должна изменяться при использовании StringStream, но ее можно повторно инициализировать. Использование rvalue (литерал String, переданный в класс) запрещено с использованием неконстантной ссылки в качестве параметра метода и конструктора setData.

Однако это не очень проверено, поэтому могут быть некоторые ошибки. Конструктор и назначение копирования / перемещения опущены (и это не должно быть: D), также использование operator=(String&) и operator=(const char*) было бы более интуитивно понятным интерфейсом для него.

class StringStream : public Stream
{
  public:
    StringStream()
    {
      setTimeout(1);
    }

    StringStream(const char * str)
    {
      setData(str);
    }

    StringStream(const char * begin, const char * end)
    {
      setData(begin, end);
    }

    explicit StringStream(String & view) // cannot be String literal (rvalue) and it gets invalidated if you change original String
    {
      setData(view);
    }

    ////////////////////////////////////
    inline void setData(const char * begin, const char * end)
    {
      m_start = begin;
      m_end = end;
      setTimeout(1);
    }

    inline void setData(const char * begin)
    {
      setData(begin, begin + strlen(begin));
    }

    inline void setData(String & view)
    {
      setData(view.c_str(), m_start + view.length());
    }

    //////////////////////////////////
    // Stream Interface:
    virtual int available() override
    {
      return m_end - m_start;
    }

    virtual int read() override
    {
      if (m_start < m_end)
      {
        return *(m_start++);
      }
      return -1;
    }

    virtual int peek() override
    {
      if (m_start < m_end)
      {
        return *m_start;
      }
      return -1;
    }

    virtual size_t write(uint8_t) override {
      return 0;
    }

  protected:
    const char * m_start{0};
    const char * m_end{0};
};

И тестовая программа будет выглядеть так:

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

void loop() {
  Serial.println("Output:");

  StringStream test{" 144, 7899, -5478"};
  Serial.println(test.parseInt());
  Serial.println(test.parseInt());
  Serial.println(test.parseInt());

  test.setData("1 2");
  Serial.println(test.parseInt());
  Serial.println(test.parseInt());

  delay(2000);
}
0 голосов
/ 22 марта 2020

Обновлен код, приведенный ниже, из строки в char *, теперь все работает.

 //Split Value
 void Split(char*  e) {
  char* v[3];
  char *p;
  int i = 0;
  p = strtok(rgb, ",");
  while(p && i < 3)
   {
    v[i] = p;
    p = strtok(NULL, ",");
    i++;
  };
  Serial.println(v[0]);
  Serial.println(v[1]);
  Serial.println(v[2]);
 };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...