我假设Serial.write(myGsm.read()) 是您要从中获取数据的位置。也就是说,你是通过串口接收数据,你想解析AT+HTTPREAD命令返回的数据。
由于您没有提供任何关于该命令在串行中返回的内容的任何线索,我将使用一个我知道输出的不同命令作为示例,如下所示:
TX=> AT+CCLK?
RX=> AT+CCLK?\n\r
\t+CCLK: "2020/03/03, 22:00:14"\n\r
所以,你将从上面的AT+CCLK? 命令得到的字符串是这样的(为了理解,我分配了一个 char 指针):
char *answer = "AT+CCLK?\n\r\t+CCLK: "2020/03/03, 22:00:14"\n\r";
您需要解析答案(本例中为char *answer)以将“数字”转换为变量。
怎么做?
你需要走过那根绳子,移动到特定的地方。例如,为了能够将2020 转换为变量,您需要位于answer[19] 的位置,然后您可以使用strtoul() 转换为整数并将其存储到变量中.
uint32_t year = strtoul(&answer[19], NULL, 10);
那么,要得到月份,你需要多走一点才能到达字符串上月份的位置:
uint32_t month = strtoul(&answer[24], NULL, 10);
等等,但您使用的是 magic numbers,换句话说,数字 19、24 是特定于这个字符串。
那么,如何让这个“走路”更聪明呢?
您可以将标记与strstr() 结合使用,以转到字符串中所需的特定点。在这种情况下,我们要将指针移动到第一个2,因此我们可以将该指针传递给strtoul(),以将其转换为整数。
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
int main() {
char *answer = "AT+CCLK?\n\r\t+CCLK: "2020/03/03, 22:00:14"\n\r";
char *token = "CCLK: \"";
char *ptr;
uint32_t year;
ptr = strstr(answer, token);
if (ptr == NULL) {
printf("Token not found\n");
return -1;
}
year = strtoul(++ptr, NULL, 10);
printf("Year = %d\n", year);
那么,为了让这段代码成为一个更通用的函数,这里是:
bool parse_answer_to_uint32(char *buff, char *tokens[], uint32_t *val)
{
char *ptr;
int i;
if (val == NULL)
return false;
for (i = 0; buff != NULL && tokens[i] != NULL; i++) {
ptr = strstr(buff, tokens[i]);
if (ptr == NULL)
return false;
buff = (ptr + strlen(tokens[i]));
}
// Here, you reached the point you want, based on the tokens you seek
if (buff == NULL)
return false;
*val = strtoul(buff, NULL, 10);
}
所以,你可以像这样调用这个函数:
char *tokens[] = { "CCLK: \"" };
uint32_t year;
if (parse_answer_to_uint32(myGsm.read().c_str(), tokens, &year) == false)
return -1;
printf("year is = %d\n", year);
printf 将根据上面的示例打印2020。
这个函数非常灵活和通用。您所需要的只是传递不同的标记以到达字符串的不同点并达到您想要的值。