【问题标题】:C++ string parsing: how to detect the end of a message?C++ 字符串解析:如何检测消息的结尾?
【发布时间】:2015-05-07 14:55:56
【问题描述】:

在嵌入式系统上,我想解析通过串行接口 (RS232) 到达的数据。数据从专有来源一次到达一行(行以\r 字符分隔,并且有一段时间)。请参阅下面的示例数据。

我想做的是解析整个消息(由多行组成)。我怎么能那样做?因为我可以 hook 每个接收到的字符(它们是通过 ISR 接收的),我想我可以将接收到的数据写入 std::stringstream 并在收到完整消息后对其进行解析。但是如何才能检测到这样一条消息的结束呢?

示例数据:

...
X20\r
R46 P20 A231 \r
R45 P20 A287 \r
R44 P20 A347 \r
X21\r
R46 P21 A284 \r
R45 P21 A341 \r
R44 P21 A436 \r
X22\r
R46 P22 A319 \r
R45 P22 A386 \r
R44 P22 A455 \r
...

在哪里

X22\r
R46 P22 A319 \r
R45 P22 A386 \r
R44 P22 A455 \r

一条消息的示例。我在乎

例如X = 22,R46 = 319,R45 = 386,R44 = 455

如何以优雅的方式区分消息?

【问题讨论】:

    标签: c++ string serial-port communication string-parsing


    【解决方案1】:

    根据您由于它是嵌入式系统而受到的限制以及您对接收到的数据的保证(似乎缺少消息的终止符号),可能会有更好的解决方案,但我的两个建议是:

    1/ 如果保证格式与您的示例中看起来一样统一,您可以将所有内容存储在缓冲区中,然后等到读取了一定数量的字符后再解析。

    2/ 一次读取一个字符,将它们存储在缓冲区中。当您读取“X”(这似乎是表示新消息开始的字符)时,只需解析缓冲区,清空它,存储“X”,然后继续。

    【讨论】:

    • 1:数据不保证完全一致(R46 P22 A5 \r vs.R46 P22 A5432 \r),但我会试一试。 2:等待下一个X会浪费一些时间(每两行数据之间有一个延迟),因此并不理想。
    • @plats1 你是说完整的消息可以有任何行数?
    • @wonkorealtime 一条消息可以只包含一个X... 行和一到四个R... 行(我的示例中的消息包含三个R... 行)。
    • @plats1 如果不能保证数据是统一的,没有可预测的长度,也没有终止字符,我个人,除了使用类似于选项 2 的东西之外,真的看不到任何其他方式上面建议。也许更聪明的人可以 =)
    • @Pzc 你可能是对的。实际系统具有决定行数的不同状态。因此,两个连续的消息很可能具有相同的大小。这个事实分散了我接受答案 2 的注意力。但我认为你是对的。我会试一试,看看这些额外延迟的影响会有多大。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-29
    • 2015-12-23
    • 2011-12-21
    • 2017-10-18
    • 1970-01-01
    • 2019-02-22
    相关资源
    最近更新 更多