Arduino - 处理结构数组的正确方法是什么?



尝试用字符串结构填充数组时,我遇到了问题。可能,我缺少在Arduino上使用指针或内存分配规则的基本内容。

请参阅下面的代码。

要填充的数据结构:

struct SMSData {
   String id;   
   String status;
   String from;
   String date;
   String text;
};

字符串解析器例程:

SMSData* readSMS(String reply) {
  debugSerial.println(reply);
  // declare a pointer to result array
  SMSData* smsArray = NULL;
  const String startPattern = F("+CMGL: ");
  int index = -1;
  // calculate result array length
  byte count = 0;
  do {
    index = reply.indexOf(startPattern, (index + 1));
    if(index < 0) {
      break;
    }
    count++;
  } while(true);
  if(count == 0) {
    return NULL;
  }
  debugSerial.println(count);
  // allocate memory to store result array
  smsArray = malloc(count * sizeof(SMSData*));
  if(smsArray == NULL) {
    return NULL;
  }
  // start parsing input String
  index = reply.indexOf(startPattern);
  int fromIndex = 0;
  while(true) {
    debugSerial.println();
    if(index < 0) {
      break;
    }
    // init data for the next element of result array
    SMSData smsData = {"", "", "", "", ""};
    // start filling result array element
    // get id
    fromIndex = index + startPattern.length();
    index = reply.indexOf(F(","), fromIndex);
    smsData.id = reply.substring(fromIndex, index);
    debugSerial.println(smsData.id);
    // get status
    fromIndex = reply.indexOf(F("""), index) + 1;
    index = reply.indexOf(F("""), fromIndex);
    smsData.status = reply.substring(fromIndex, index);
    debugSerial.println(smsData.status);
    // get phone
    fromIndex = reply.indexOf(F("""), index + 1) + 1;
    index = reply.indexOf(F("""), fromIndex);
    smsData.from = reply.substring(fromIndex, index);    
    debugSerial.println(smsData.from);
    // get date
    fromIndex = reply.indexOf(F("""), index + 1) + 1;
    index = reply.indexOf(F("""), fromIndex);
    smsData.date = reply.substring(fromIndex, index);
    debugSerial.println(smsData.date);
    // get text
    fromIndex = index + 1;
    index = reply.indexOf(startPattern, fromIndex);
    if(index < 0) {
      smsData.text = reply.substring(fromIndex);
    } else {
      smsData.text = reply.substring(fromIndex, index);
    }
    smsData.text.trim();
    debugSerial.println(smsData.text);
    // add filled element to result array
    smsArray[count - 1] = smsData;
  }
  return smsArray;
}

输出解析数据:

SMSData* smsArray = readSMS(reply);
int count = sizeof(smsArray);
debugSerial.print(F("SMS count:"));
debugSerial.println(count);
for(int i = 0; i < count; i++) {
  SMSData smsData = smsArray[i];
  debugSerial.print(F("id: "));
  debugSerial.println(smsData.id);
  debugSerial.print(F("status: "));
  debugSerial.println(smsData.status);
  debugSerial.print(F("from: "));
  debugSerial.println(smsData.from);
  debugSerial.print(F("date: "));
  debugSerial.println(smsData.date);
  debugSerial.print(F("text: "));
  debugSerial.println(smsData.text);
}
free(smsArray);

虚拟字符串到解析:

String reply = "+CMGL: 1,"REC READ","+123456789012",,"2017/09/26,18:31:25+03"rnHirn+CMGL: 2,"REC READ","+123456789012",,"2017/09/26,18:34:25+03"rnHellorn";

当我运行草图时,输出通常是不同的,但总是断裂和不完整,例如

+CMGL: 1,"REC READ","+123456789012",,"2017/09/26,18:31:25+03"
Hi
+CMGL: 2,"REC READ","+123456789012",,"2017/09/26,18:34:25+03"
Hello
2
1
REC READ
+12345678905+03 017/09/26,18:31:25+03
Hi
2
REC REA

您可以根据输出看到,它会记录整个输入字符串,开始解析,通过第一个循环迭代(从结构字段中混合字符串),启动第二个迭代填充结构,再次使用重型混合字符串然后停止在中间做出响应。

现在,除了记忆分配的问题外,我没有看到这种行为的理由,但是我找不到我在做错了什么。

您的任何帮助都将不胜感激。

首先,您的代码是C ,而不是严格的C,这没关系,但是标签应更改。这是我在您的代码中发现的一些问题...

    ///// Passing nothing, println requires one or two parameters
    debugSerial.println();

请参阅println上的文档

    // init data for the next element of result array
    ////// You are creating a local buffer, it will go out of scope
    ////// when you leave the function.  And you are trying to store
    ////// it in an array that you return from your function.
    ////// And you are changing the data with pass through your loop
    ////// (2 passes).
    SMSData smsData = {"", "", "", "", ""};
    //...
    ////// You should be assigning an allocated struct pointer
    ////// count is not changing, you are only assigning the last
    ////// element of the array.
    smsArray[count - 1] = smsData;

///// This will not work.  smsArray is a pointer and you have lost
///// the information about how much memory was allocated and assigned to
///// the pointer.
SMSData* smsArray = readSMS(reply);
int count = sizeof(smsArray);

我们用来将C样式指针用作数组的一个技巧是分配一个比我们需要的指针块,并确保它们都设置为null(使用calloc(使用calloc()而不是malloc())。然后,我们将在数组中设置EACCH指针,除了最后一个。最后,我们将通过数组迭代直到指针为null,指示数据的末尾。

您应该在SMSarray中存储分配的数据,您应该释放(销毁)该数据以及数组。

所以,您的代码可能看起来像...

SMSData** smsArray = NULL;
smsArray = (SMSData **)calloc(count+1, sizeof(SMSData *));
int idx = 0;
//...
    SMSData* smsData = new smsData();
    smsData->id = ""; //etc. for the rest of the fields
    //...
    smsArray[idx++] = smsData;
    //..

返回后...

SMSData ** smsArray = readSMS(reply);
SMSData ** ptr = smsArray;
while (ptr != NULL) {
    //do stuff with ptr->whatever
    destroy(ptr); //destroy since allocated with new
    ptr++;
}
free(smsArray); //free since allocated with malloc

这不是最好的代码(并且可能有错误,我现在无法访问编译器)。但它试图坚持您的方法。

相关内容

  • 没有找到相关文章

最新更新