【问题标题】:Arduino split char* based on delimiter to valueArduino 拆分字符 * 基于分隔符到值
【发布时间】:2020-03-22 17:59:40
【问题描述】:

感谢您的时间,所以我有一个来自 mqtt 的 Char*

我想将其分解为 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]);
}

【问题讨论】:

  • 然后选择 C ​​或 C++。每种语言使用不同的函数。
  • 查看strtok 文档后,您的方法似乎很好。你有什么问题?你得到什么输出? “没有运气”不是很具有描述性
  • 你调用split 并带有一个字符串。这不是 strtok 的有效参数,因为它修改了提供的字符串。
  • 你上面的伪代码没有任何意义。您谈论拆分字符串,但使用整数来存储结果。此外,括号中的某些整数与输入字符串不同。在准备问题时,您应该更加精确。
  • 我认为关键可能在于@Gerhardh 所说的。像char test[] = "255,240,230"; 一样创建一个测试char* 并将that 传递给Split

标签: c++ c arduino


【解决方案1】:

将下面的代码从字符串更新为 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]);
 };

【讨论】:

    【解决方案2】:

    因为这是一个经常被问到的问题,我建议更像是在 C 字符串上使用继承 Stream interface 的包装类(它也可以从 Arduino String 对象初始化)。

    然而,使用 Arduino String 类很棘手,因为在使用 StringStream 期间不应更改原始字符串,但可以再次重新初始化它。通过使用非 const 引用作为setData 方法和构造函数的参数,禁止使用右值(String 字面量,传递给类)。

    但是它没有经过太多测试,所以可能会有一些错误。复制/移动构造函数和分配被省略(它不应该是:D),也使用operator=(String&amp;)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);
    }
    

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 2020-06-18
      • 2011-11-28
      • 2021-12-17
      • 2014-03-13
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2016-10-30
      相关资源
      最近更新 更多