【问题标题】:getting the first n elements of a specified char array arduino获取指定字符数组的前 n 个元素
【发布时间】:2020-07-22 00:26:11
【问题描述】:

如果程序看到,我的目标是从串行读取一些字符串,例如 234124!3455addg#5867 !它应该开始将它添加到一个 char 数组中,如果它看到 # 它应该返回该 char 数组的前 4 个元素,对于我的示例,返回应该是 3455。我该如何解决它?我使用 String 类制作了这个,但我需要将它实现为 char 数组。 我对 arduino 很陌生,所以请说清楚,谢谢。 这是我的代码:

const char *s = "123123123!0037selam#aaaaSDSDa";
const char *CHAR1 = "!";
const char *CHAR2 = "#";

char *target = NULL;
char *start, *end;

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

void loop() {
    if ( start = strstr( s, CHAR1 ) )
    {
        start += strlen( CHAR1 );
        if ( end = strstr( start, CHAR2 ) )
        {
            target = ( char * )malloc( end - start + 1 );
            memcpy( target, start, end - start );
            target[end - start] = '\0';
        }
    }

    if ( target )
    {
        for(int i=0; i<4;i++)
            Serial.print( target[i]);
    }

    free( target );
    return 0;
}

【问题讨论】:

  • 您提供了一些代码,但没有解释您遇到的问题。请注意,Arduino 使用 C++ 而不是 C。
  • 我的问题是它不能完全工作。我无法做出任何有意义的事情,所以我向问题寻求帮助。

标签: c++ arrays arduino char arduino-uno


【解决方案1】:

我按照您的代码进行了一些更改,以作为您的示例。

如果你的字符串总是这样,! 总是出现在# 之前,并且在它们之间总会有一些数字需要处理,那么你可以做一些循环来等待这些标记。

所以,基本上:

  • 循环继续检查!标记的接收;
  • 循环使用isdigit() 函数不断检查有效数字;
  • 循环查找结束标记,#

但同样,此算法适用于您提供的示例。

 #define MAXSIZE (200)

    char Tmp[MAXSIZE];

    void setup() {
        Serial.begin(9600);
        Serial.println("Enter a Message");
    }
    void loop() {
        int counter, i;
        char received;

        while (Serial.available() <= 0) {
          /* keep in the loop*/
        }

        while (Serial.read() != '!') {
            /* keep waiting the '!' */
        }

        for (i = 0; i < 4; i++) {
            if (isdigit((received = Serial.read())) == 0)
                break;
            Tmp[counter++] =  received;
            delay(10);
        }
        while (Serial.read() != '#') {
            /* keep waiting the '!' */
        }
        Tmp[counter] = 0;

        Serial.write(Tmp, strlen(Tmp));

        newPack(Tmp);

        // after you are done, make sure to clean up
        // your buffer for the next round
        counter = 0;
        memset(Tmp, 0, MAXSIZE);
    }

另外,我注意到您在 loop() 函数的末尾返回。 你不应该这样做,因为像 Arduino 这样的嵌入式系统必须有一个无限循环才能继续运行。

【讨论】:

  • 它没有用。在某处应该有 Serial.print()
  • 您能更具体一点,那么您的问题是什么?我不明白。
  • 当我输入 234124!3455addg#5867 程序应该返回 3455 但是当我运行它时你的代码没有做任何事情
  • 让问题更容易理解。我想在两个字符之间获取字符!和#首先
  • 我编辑将它打印到序列中,它存储在Tmp 中。 Tmp 是保留您正在寻找的数字的人。
【解决方案2】:

我认为这是一种更简单的方法。这取决于是否有未明确说明的要求。

有几点值得一提,

  1. 您希望返回 '!' 后面的前 4 个字节,因此您 只需要缓冲4个字符
  2. 我现在没有准备好所有的电缆,所以我刚刚 拼凑一些可以在 PC 上运行的东西。在你的情况下,而不是 返回您刚刚输出的字符串缓冲区的副本 Serial.print

代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;

class dummy
{
    public:
        dummy()
        {
            const char *testData = "234124!3455addg#5867";
            int dataLen = strlen(testData);
            mData = new char[dataLen+1];
            strcpy(mData, testData);
            mTotal = strlen(testData);
            mIndex = 0;
        }
        int available()
        {
            return mTotal - mIndex;
        }
        char read()
        {
            return mData[mIndex++];
        }
    private:
        char *mData;
        int mIndex;
        int mTotal;
};

char *testFunc()
{
    dummy *Serial = new dummy();
/// -------- 8< ------------ cut here until the next pair of scissors. put inside the loop function
/// your code does all of the functionality (reading and buffering) inside a single iteration of loop(). 
/// Normally, I'd expect a single character to be read each time. I'd expect loop() to be 
/// run 16 times before a result was output, since # is the 16th character of the string.
    char tmpBuffer[5] = {0};
    int bufferIndex = 0;
    bool marker1Seen = false;

    while (Serial->available() > 0)
    {
        char received = Serial->read();
        if (received == '!')
        {
            marker1Seen = true;
        }

        else if (received == '#')
        {
            return strdup(tmpBuffer);
        }

        else if (marker1Seen == true && bufferIndex < 4)
        {
            tmpBuffer[bufferIndex++] = received;
        }
    }
    // shouldn't get here if the input is well-formed
    return NULL;
/// -------- 8< ------------ cut here
}

int main()
{
    char *result = testFunc();
    cout << result;
    delete result;
}

【讨论】:

  • 那么哪一部分应该在循环中,哪一部分应该在设置中。正如我所说,我对此很陌生。
  • 当然,抱歉。我将使用一些 cmets 编辑代码。请给我一分钟左右。我只是尝试复制loop() 函数的功能。
  • 那我该如何打印结果呢?
  • HERE 我发布了关于这个主题的另一个问题,你能帮帮我吗
猜你喜欢
  • 2011-04-12
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
  • 2017-02-27
  • 2011-07-08
相关资源
最近更新 更多