函数调用重置传递全局结构域

时间:2016-04-15 06:04:58

标签: c++ struct arduino strtok

参考下面的代码:在调用函数CheckSMS并传递struct * DB1之后,根据strtok调用更新字段。此函数读取并解析文本消息,将其内容存储到DB结构的char *字段中。

在主循环中,我在调用Serial.println(DB1.last_order)函数之前和之后调用了CheckSMS。如果我收到了一个文本,则在主循环中正确打印顺序,但是在下次调用CheckSMS时,DB1.last_order被清除,替换为\ n或NULL或其他内容。我无法弄清楚为什么DB1.last_order不保留其值,而是每次调用CheckSMS时都会覆盖它。谢谢你的帮助。

注意 - 所有文本消息都包含“CMT +”,因此只有在收到文本时才会写入DB1。在没有收到任何文本时调用CheckSMS应该只是跳过。

  int CheckSMS(Robot *DB1) {

  int j = 0;
  char  response[100];
  char  *pch;
  unsigned long previous;

  memset(response, '\0', 100);

  while(Serial2.available()>0){
       response[j] = Serial2.read();
       j++;
       Serial.println("inc");
  }

  delay(100);
  if (strstr(response, "CMT:") != NULL){ 
      DB1->new_message = strtok(response, " ,");
      DB1->last_phone = strtok(NULL, " ,");
      pch = strtok(NULL, " ,");
      DB1->last_date = strtok(NULL, " ,");
      DB1->last_time = strtok(NULL, " ,\n");
      DB1->last_order = strtok(NULL," ,\n");
      new_message = 1;  

  }

  else{
  }

  return 0;
}

2 个答案:

答案 0 :(得分:2)

strtok函数返回指向您正在标记的字符串的指针,在您的情况下返回本地数组response。当函数返回时,response数组超出范围并消失,使您的结构指向不再存在的字符串,并为您提供未定义的行为

您有几个解决方案:

  • 使用malloc动态分配字符串,但是您必须将其保存在结构中,以便在完成结构后free
  • 制作response数组static,但接下来对该函数的调用将具有相同的数组,以便更新旧数据
  • 传入一个字符串来存储响应并使用该字符串,该字符串的生命周期必须至少与结构一样长,并且不会更改内容。字符串当然可以是结构本身的一部分

答案 1 :(得分:0)

Joachim给出的答案是正确的,我只想补充一点,你也可以改变Robot结构来包含char数组(如:char new_message[MAX_BUF_CHARS];等)。一定要有足够的空间。然后,不是分配从strtok返回的指针,而是复制那里的字符串。