0

I have a circular buffer of of ASCII text that is 1000 bytes long. It is going to be constantly being updated and appended to.

My problem is I am using strstr() to pinpoint where a section of data starts by looking for a "$GPRMC" and I am looking for a "\r\n" to indicate the end of that block. The length will be variable and I need to find a way to determine the length of each block of data (string data) so I can then parse it further and store it into variable etc.

I tried subtracting the two pointers returned from strstr() but got a number wayyyyy to big (it was upwards of 6 billion) but in reality the string lengths are like 60-80 characters apart.

char *data, *end;
int diff;

data = strstr(&gps_buffer[gps_head], "$GPRMC");
end = strstr(&gps_buffer[gps_head], "\r\n");

diff = end - data;
Wesley Carlsen
  • 137
  • 3
  • 19
  • 1
    What is the question ? Can you show your code ? – quantdev Jun 03 '14 at 19:48
  • yes. I am putting it in now... my question is why the number is so large. – Wesley Carlsen Jun 03 '14 at 19:49
  • `strstr` is not suitable for use with circular buffers - it has no idea of wrapping around. – Sergey Kalinichenko Jun 03 '14 at 19:50
  • i am handling the wrapping around with local variables however: namely a head and a tail which increment and reset to 0 where applicable – Wesley Carlsen Jun 03 '14 at 19:50
  • Using an underlying `std::array` for the buffer and `std::string`, `std::find()` operations might work better than using `strstr()`. – πάντα ῥεῖ Jun 03 '14 at 19:51
  • @WesleyCarlsen *You* do handle the wraparound, but `strstr` does *not* handle it. When the buffer ends and you are supposed to wrap around, `strstr` keeps going forward. – Sergey Kalinichenko Jun 03 '14 at 19:53
  • @dasblinkenlight well how far will it go? there's no parameter for buffer length, so will strstr just go on for infinity? or until it hits null character? – Wesley Carlsen Jun 03 '14 at 19:56
  • @WesleyCarlsen Once `strstr` goes past the end of the buffer, it is undefined behavior. It would continue on until it finds a zero, so more likely than not it wouldn't crash. – Sergey Kalinichenko Jun 03 '14 at 20:01
  • I actually had end-data previously. I was experimenting with using strlen(data)-strlen(end) and got rid of the strlen before posting here and forgot to reverse the order... my bad. But in fact I was seeing the issue with the large difference when it was end - data. – Wesley Carlsen Jun 03 '14 at 20:04
  • Let me give actual numbers to make it more concrete: start = 40002250, end = 4000228C, diff = 60073750608 – Wesley Carlsen Jun 03 '14 at 20:10
  • @WesleyCarlsen That does not look correct, because 4000228C-40002250 is 3C (60 in decimal). – Sergey Kalinichenko Jun 03 '14 at 20:18
  • Right, which is why I was so confused. I actually found this page which apparently says you can't perform arithmetic on pointers: http://stackoverflow.com/questions/2117486/c-pointer-arithmetic – Wesley Carlsen Jun 03 '14 at 20:21
  • @WesleyCarlsen you can subtract one pointer from another so long as they both point into the same buffer (or one past the end), as explained by the top answer in that link. Your "actual numbers" are impossible. – M.M Jun 03 '14 at 23:06

1 Answers1

2

You cannot use strstr with a circular buffer, because it does not know where to wrap around. Consider this buffer layout:

o , w o r l d ! . . H e l l
              ^     ^
              |     |
         end--+     +- start

Your program would fail to find Hello, because it's ending is before its beginning. Therefore, you wold need to write your own circ_strstr that takes a buffer along with its length in addition to the initial position and the search string.

Your program would have issues with a linear buffer, too, because it could find \r\n from a previous token. You need to start the search for the closing token from the position after the point where the initial token has been found. Otherwise, your end could be less than data, so subtracting would produce a negative number (which would be re-interpreted as a huge unsigned value).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Another problem with `strstr`: What if the multi-character markers cross the wraparound point? They might never be found because they don't exist in the buffer. `strstr` will happily go marching past the end of the buffer because it doesn't know about the wraparound. – David Hammen Jun 03 '14 at 20:11
  • So maybe strstr() is the wrong way to go about this. Maybe I need to scratch the idea and go back to brainstorming – Wesley Carlsen Jun 03 '14 at 20:15
  • @WesleyCarlsen You can write your own `circ_strstr` which knows that the buffer is circular. It shouldn't be too hard. – Sergey Kalinichenko Jun 03 '14 at 20:19
  • True. That may be the best approach – Wesley Carlsen Jun 03 '14 at 20:20