Reputation: 23
I'm new to this whole embedded thinking about memory etc. I wonder wheter ther is the most efficient way of parsing the strings of known structure, but unknown length on embedded system. (some approaches every embedded developer should know are welcome).
I have structures like the one bold below coming to my avr. Those are basicly commands determining certain actions to be performed by my avr. I don´t want to use a String-class, because of reasons.
number delimiter string delimiter string
I don´t have any power over the protocol. I have a solution using a function with strtok()
, strcpy()
in it. I fill the array with the tokens an then i have some if/else if conditions to perform actions.
But I wonder if there is a solution like state machine (reading character by character) or similiar which works more efficient on embedded systems. I searched for quite a time now and i would be thankful to receive any hints on this fairly common promblem of string parsing.
Thx for the input. I´m not asking for a solution, but for an approach.
Upvotes: 0
Views: 2225
Reputation: 28932
Assuming you are trying to parse something non-trivial, take a look at flex and bison.
There is quite a steep learning curve but it has two big advantages over other approaches.
Upvotes: 1
Reputation: 7812
I disagree with automatically just using strtok for embedded system, since it modifies the first argument (large strings can often be read only). It is fairly simple to use strchr()
, strspn() or strcspn()
to accomplish the same objectives and you can control whether you modify the original string and use a pointer or strncpy()
and null terminate it to write-able memory.
Upvotes: 2
Reputation: 9354
A simple while loop with an array of buffers would save some of the processing, along the following lines (no error checking here or anything)
pos = 0;
while (c = get_next_char(), c != delim) { buff[BUFF_N][pos++] = c; }
buff[BUFF_N][pos] = 0;
pos = 0;
while (c = get_next_char(), c != delim) { buff[BUFF_S1][pos++] = c; }
buff[BUFF_S1][pos] = 0;
pos = 0;
while (c = get_next_char(), c != '\n') { buff[BUFF_S2][pos++] = c; }
buff[BUFF_S2][pos] = 0;
which would be moderately more efficient that using strtok and strcpy as you're reading the characters into the right place.
Upvotes: 2
Reputation: 27478
I think strtok() should be enough. Depending on how constrained your hardware is you should avoid strcpy() as you will end up holding the string twice in memory.
Use strtok() to locate your strings then assign the address to a pointer, for later use. That way you have the original string however long it may be plus three or four pointers which would consume a fixed 12/16 bytes.
Upvotes: 0