C++中将uint16_t数组转换为逗号分隔char数组问题咨询
问题根因分析
- 最初代码错误:直接把数组名
status传给sprintf的%u格式符,数组名本质是数组首地址的指针,所以输出的是内存地址数值而非数组元素值 - 逐元素拼接版本两个错误:
- 函数内重复定义了局部
uint16_t status[sz]数组,覆盖了全局已经读取到数据的status数组,局部数组未初始化值为随机垃圾值 - 拼接完成后指针
p已经移动到了字符串末尾的结束符位置,调用publish传入p相当于传入空字符串
- 函数内重复定义了局部
正确实现方案
// 保持全局的status数组定义不变 uint16_t status[8]; long lastMsg = 0; void loop() { mb.task(); yield(); if (!client.connected()) { reconnect(); } client.loop(); long now = millis(); if (now - lastMsg > 3000) { lastMsg = now; // 读取寄存器到全局status数组 mb.readHreg(SLAVE_ID, 0x0001, status, 8, cbWrite); // 定义足够大的缓冲区,单个uint16_t最大是5位数字+逗号空格,8个最多占56字节,开80足够 char str[80] = {0}; // 初始化为0避免乱码 char* p = str; int offset; // 拼接第一个元素 offset = sprintf(p, "%u", status[0]); p += offset; // 拼接后续元素,前面加逗号空格 for (int i = 1; i < 8; i++) { offset = sprintf(p, ", %u", status[i]); p += offset; } // 传入字符串首地址str,而非移动后的指针p client.publish("device1/relaysChannelStatus", str); } }
简化实现方案
如果担心sprintf缓冲区溢出,也可以直接用Arduino原生String类拼接,代码更简洁:
// 读取寄存器后的拼接逻辑 String payload = String(status[0]); for (int i = 1; i < 8; i++) { payload += ", " + String(status[i]); } client.publish("device1/relaysChannelStatus", payload.c_str());
内容的提问来源于stack exchange,提问作者xxxbud
相关产品推荐
相关产品推荐

