hetao7241 发表于 2022-7-24 00:46:02

发现ESP8266收到的数据到晚上就丢了,必须将数据存储到变量里面

最近在使用ESP8266,用arduino语言编程。为了方便,很多时候使用字符串变量,如下:

const char *phone = "";
const char *NameDevice = "";
String T_phone = "";
String DeviceName = "";

void callback(char *topic, byte *payload, unsigned int length)
{
String msg = "";
for (int i = 0; i < length; i++)
{
    msg += (char)payload;
}
      
T_phone = msg.substring(msg.indexOf("data_phone\":") + 12, msg.indexOf(",\"userName"));
DeviceName = msg.substring(msg.indexOf("userName\":") + 10, msg.indexOf("}"));
phone= T_phone.c_str();
NameDevice = DeviceName.c_str();
   
}


void send_sms( )
{
Serial.println("send sms.........");
char param = {0};
sprintf(param, "{\"phone\": \"%s\",\"store\": \"%s\",\"temp\":%.2f,\"hum\":%.2f}\0", phone,NameDevice, T_Device_temp, T_Device_hump);
client.publish(Mqtt_sms_topic, param);
}

发现ESP8266收到的phone和NameDevice数据到晚上就丢了。
后来看了些资料,必须将数据存储到变量里面去,于是改成下面的程序:

const char *phone= "";
const char *NameDevice = "";
String T_phone = "";
String DeviceName = "";
char arr_phone={0};
char arr_NameDevice={0};



void callback(char *topic, byte *payload, unsigned int length)
{
String msg = "";
for (int i = 0; i < length; i++)
{
    msg += (char)payload;
}
      
T_phone = msg.substring(msg.indexOf("data_phone\":") + 12, msg.indexOf(",\"userName"));
DeviceName = msg.substring(msg.indexOf("userName\":") + 10, msg.indexOf("}"));
phone= T_phone.c_str();
strncpy(arr_phone,phone,strlen(phone));// phone存入数组
NameDevice = DeviceName.c_str();
strncpy(arr_NameDevice,NameDevice,strlen(NameDevice));//NameDevice 存入数组
   
}

void send_sms( )
{
char param = {0};
phone=arr_phone;//从数组取出数据 phone
NameDevice=arr_NameDevice;//从数组取出数据NameDevice
sprintf(param, "{\"phone\": \"%s\",\"store\": \"%s\",\"temp\":%.2f,\"hum\":%.2f}\0", phone,NameDevice, T_Device_temp, T_Device_hump);
client.publish(Mqtt_sms_topic, param);
}

现在运行很好,再也没有丢失数据 phone和数据NameDevice

t3486784401 发表于 2022-7-24 03:26:51

本帖最后由 t3486784401 于 2022-7-24 03:27 编辑

1. 作为一个全局的 String 对象,过早地返回 c_str( ) 并保存,很显然一个修改/重分配内存就会搞坏,应该用到再调用




2. 都用到 strncpy 了,还要配合 strlen 这就不优雅了: strncpy(d, s, strlen(s))等同strcpy(d, s)


这代码要是哪里粘贴的也就算了,要是 LZ 自己写的,建议好好复习 C 语言

hetao7241 发表于 2022-7-24 05:53:27

谢谢楼上大侠!

solojimes 发表于 2022-7-24 13:59:12

t3486784401 发表于 2022-7-24 03:26
1. 作为一个全局的 String 对象,过早地返回 c_str( ) 并保存,很显然一个修改/重分配内存就会搞坏,应该用 ...
(引用自2楼)

这句话怎么理解,可以详细说一下吗?

t3486784401 发表于 2022-7-24 14:17:44

solojimes 发表于 2022-7-24 13:59
这句话怎么理解,可以详细说一下吗?
(引用自4楼)

String 作为广义字串类,会自动维护内存。你返回的c_str 指针只要字串维护一次就失效了。

应该随用随取

armok. 发表于 2022-8-12 09:32:27

“C++中string、char[]、const char*的转换”标题不合格。已经帮你修改(注意:主题发出24小时后就不能修改帖子)

帖子标题必须能充分说明帖子的内容。如你要问AVR的ADC如何才能测量得比较准确,“AVR的ADC如何消除干扰测量得比较准确?”是合格的标题。不合格举例:
    1:小女子冰天雪地裸体跪求解决方法
    2:救命啊...
    3:高手请出招,一个无法解决的AVR问题
    4:一个困扰学习单片机初学者,惊动单片机开发者的难题
    5:AVR的ADC测量   (点评:你到底是问问题,或是有技术心得与大家分享?)
页: [1]
查看完整版本: 发现ESP8266收到的数据到晚上就丢了,必须将数据存储到变量里面