Arduino读取两个MQTT主题并将Payload存入不同变量的问题求助
问题原因与解决方法
问题根源
C语言中char类型字符串必须以**空字符'\0'**作为结束标志,你的代码仅将MQTT payload的字符复制到数组中,未添加这个终止符。串口打印Serial.println()时会持续读取内存直到遇到'\0',因此会越界读取到相邻变量的内容,导致两个变量的内容拼接输出。同时你定义的数组char myTemp[5]空间不足,无法同时容纳有效字符和终止符,进一步加剧了越界问题。
解决方案
1. 调整数组大小,预留终止符空间
将数组定义从char myTemp[5]改为char myTemp[6],确保能容纳最多5个有效字符+1个'\0'。
2. 复制payload后添加终止符
无论用循环复制还是字符串函数复制,都要手动添加'\0'标记字符串结束位置,同时限制复制的字符数,避免数组越界。
修改后的完整代码
// 数组大小改为6,预留空字符位置 char myTemp[6]; char myHum[6]; void callback(char *topic, byte *payload, unsigned int length) { Serial.print("Message arrived in topic: "); Serial.println(topic); if (String(topic) == "arduino/temp") { Serial.println(strcmp(topic, "arduino/temp") == 0); Serial.print("Message:"); // 用Serial.write直接打印payload,替代循环更高效 Serial.write(payload, length); Serial.println(); // 安全复制payload到数组:最多复制5个字符(数组大小-1) strncpy(myTemp, (char*)payload, sizeof(myTemp)-1); // 强制添加字符串终止符,确保不会越界 myTemp[sizeof(myTemp)-1] = '\0'; Serial.println(myTemp); Serial.println("-----------------------"); } else { Serial.println(strcmp(topic, "arduino/humid") == 0); Serial.print("Message:"); Serial.write(payload, length); Serial.println(); strncpy(myHum, (char*)payload, sizeof(myHum)-1); myHum[sizeof(myHum)-1] = '\0'; Serial.println(myHum); Serial.println("-----------------------"); } }
关键修改点说明
- 数组扩容:从5位改为6位,留出
'\0'的位置 - 使用
strncpy替代手动循环:更简洁安全,限制复制字符数为数组大小-1,避免越界 - 强制添加终止符:即使payload长度超过数组预留空间,也能保证字符串正常结束
- 用
Serial.write(payload, length)打印payload:无需循环逐个字符打印,效率更高
内容的提问来源于stack exchange,提问作者paulr
相关产品推荐
相关产品推荐

