On an embedded system, I would like to parse data that arrives via serial interface (RS232). The data arrives one line at a time (lines are separated with \r
characters and by some time) from a proprietary source. See example data below.
What I would like to do is to parse whole messages (that consist of multiple lines). How could I do that? As I can hook on every received char (they are received via ISR), I think I could write the received data to a std::stringstream
and parse it after a complete message was received. But how can one detect the end of such a message?
Example data:
...
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
...
where
X22\r
R46 P22 A319 \r
R45 P22 A386 \r
R44 P22 A455 \r
is an example for one message. I care for
e.g. X = 22
, R46 = 319
, R45 = 386
, R44 = 455
How can I discriminate the messages in an elegant way?
Depending on what kind of limitations you have due to it being an embedded system and what guarantees you have on the received data (which seem to lack a terminating symbol for a message) there's probably better solutions but my two suggestions would be:
1/ If the format is guaranteed to be as uniform as it looks in your example you can just store everything in a buffer and wait until a set number of characters have been read and then parse.
2/ Read one character at a time, storing them in a buffer. When you read a 'X' (which seems to be the character signalling the beginning of a new message) just parse the buffer, empty it, store the 'X' and then keep going.