sscanf使用小结

需求背景
在项目的mqtt相关业务中需要解析topic字符串,如下格式示例 “homeassistant/switch/112233AABBCC-01/set”,需要解析获取到字段"112233AABBCC"所代表的目标设备MAC地址、字段"01"所代表的操作位、字段"set"所代表的操作命令;

实施方法

uint8_t macTarget[MWIFI_ADDR_LEN] = {0}; //MWIFI_ADDR_LEN = 6
uint8_t opBitNum = 0;
char eventTopic_temp[128] = {0};
char opreatTopic[16] = {0};

memcpy(eventTopic_temp, event->topic, sizeof(char) * event->topic_len); //设定event->topic的字符串为"homeassistant/switch/112233AABBCC-01/set"
sscanf(eventTopic_temp, "%*[^/]/%*[^/]/%02X%02X%02X%02X%02X%02X-%d/%s", 
						 (int *)&macTarget[0],
						 (int *)&macTarget[1],
						 (int *)&macTarget[2],
						 (int *)&macTarget[3],
						 (int *)&macTarget[4],
						 (int *)&macTarget[5],
						 (int *)&opBitNum,
					  	 opreatTopic);

%*[^/] : 取到指定字符为止的字符串(%[^/] )并过滤掉不要(%*[^/] );

实施时遇到问题
运行功能后macTarget、opBitNum、opreatTopic都可以正常获取,但是运行完这段代码后,其他变量内存收到了扰乱:

uint8_t macTarget[MWIFI_ADDR_LEN] = {0}; //MWIFI_ADDR_LEN = 6
uint8_t opBitNum = 0;
char eventTopic_temp[128] = {0};
char opreatTopic[16] = {0};

uint8_t haDevSelfMac[MWIFI_ADDR_LEN] = {0};

esp_wifi_get_mac(ESP_IF_WIFI_STA, haDevSelfMac);
printf("self-mac:%02X%02X%02X%02X%02X%02X"); //此处获取打印值为:"self-mac:345C6D8729D8"

memcpy(eventTopic_temp, event->topic, sizeof(char) * event->topic_len); //设定event->topic的字符串为"homeassistant/switch/112233AABBCC-01/set"
sscanf(eventTopic_temp, "%*[^/]/%*[^/]/%02X%02X%02X%02X%02X%02X-%d/%s", 
						 (int *)&macTarget[0],
						 (int *)&macTarget[1],
						 (int *)&macTarget[2],
						 (int *)&macTarget[3],
						 (int *)&macTarget[4],
						 (int *)&macTarget[5],
						 (int *)&opBitNum,
					  	 opreatTopic);

printf("self-mac:%02X%02X%02X%02X%02X%02X"); //此处获取打印值为:"self-mac:0000008729D8" -前三个字节内存被清零

分析解决问题
字符串"%02X"表明必须将输入字符串作为一个int类型来保存到目标地址处,应该是使用指针强转(int *)破坏了相关内存布局;
故重新编写功能为:

		uint8_t loop = 0;
		int macTarget_16b[MWIFI_ADDR_LEN] = {0};
		uint8_t macTarget_8b[MWIFI_ADDR_LEN] = {0};
		int opBitNum_16b = 0;
		char eventTopic_temp[128] = {0};
		char opreatTopic[16] = {0};

		memcpy(eventTopic_temp, event->topic, sizeof(char) * event->topic_len);
		sscanf(eventTopic_temp, "%*[^/]/%*[^/]/%02X%02X%02X%02X%02X%02X-%d/%s", //避免内存布局被sscanf打乱,强制使用int型缓冲中转
								 &macTarget_16b[0],
								 &macTarget_16b[1],
								 &macTarget_16b[2],
								 &macTarget_16b[3],
								 &macTarget_16b[4],
								 &macTarget_16b[5],
								 &opBitNum_16b,
							  	 opreatTopic);
		for(loop = 0; loop < MWIFI_ADDR_LEN; loop ++){
			
			macTarget_8b[loop] = macTarget_16b[loop];
		}

问题解决,变量内存恢复正常。

你可能感兴趣的:(工程应用总结,字符串,c++)