【发布时间】:2019-06-02 08:51:42
【问题描述】:
我需要扫描来自串行流的各种传入消息,以检查它们是否包含此字符串:
“所有内容:已收到:switchX yy(y)”
其中 X = 1 到 9 并且 yy(y) 是“开”或“关”。即“一切:收到:switch4 on”或“一切:收到:switch2 off”等。
我在 ATMega328 上使用以下代码进行检查并将相关变量传递给传输()函数:
valid_data = sscanf(serial_buffer, "Everything: Received: switch%u %s", &switch_number, command);
if(valid_data == 2)
{
if(strcmp(command, "on") == 0)
{
transmit(switch_number, 1);
}
if(strcmp(command, "off") == 0)
{
transmit(switch_number, 0);
}
}
当 serial_buffer 输入 ISR 检测到“\n”时触发检查。 '\0' 附加到串行流以终止字符串。
它有效,我并没有受到空间/处理能力的推动,但我只是想知道这是否是实现所需结果的最佳方式?
【问题讨论】:
-
如果需要,您可以编写一个通用解析器,或者使用
strstr找到正确的偏移量以开始读取。 -
“最佳”的方式是什么指标?讨论各种方法的优缺点很有趣也很有意义,但不太适合 SO 的问答形式。一般来说,我很少推荐使用
scanf做任何事情,因为它在检测到的分隔符和其他类似的东西方面定义不明确,而是倾向于更喜欢fgets并更手动地解析结果字符串,但如果你可以别管它,使用scanf更紧凑。 -
sscanf是适合这项工作的工具。您可以通过在字符串末尾添加\n来强制执行更严格的输入格式,并通过添加%4s来提高安全性,以确保最后一个令牌(命令)不会溢出您的输入缓冲区(它是 4 个字符,因为 @987654330 @ 字符存储在字符串的末尾,由sscanf自动附加。 -
aside:如果您的第一个条件匹配,请使用
else避免测试另一个。 -
与此类解析问题一样,如果字符串与格式不匹配,请提供所需的结果 - 或者您是否建议 string 始终格式正确?