'C' получить длину подстроки из большого буфера, используя strstr() и вычитая два указателя

У меня есть круговой буфер текста ASCII длиной 1000 байт. Он будет постоянно обновляться и дополняться.

Моя проблема в том, что я использую strstr(), чтобы определить, где начинается раздел данных, ища «$ GPRMC», и я ищу «\ r \ n», чтобы указать конец этого блока. Длина будет переменной, и мне нужно найти способ определить длину каждого блока данных (строковых данных), чтобы я мог затем проанализировать его и сохранить в переменной и т. д.

Я попытался вычесть два указателя, возвращенные из strstr(), но получил число, которое сильно увеличилось (оно было выше 6 миллиардов), но на самом деле длина строки составляет около 60-80 символов.

char *data, *end;
int diff;

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

diff = end - data;

person Wesley Carlsen    schedule 03.06.2014    source источник
comment
В чем вопрос ? Можете ли вы показать свой код?   -  person quantdev    schedule 03.06.2014
comment
да. Я вставляю это сейчас ... мой вопрос в том, почему число такое большое.   -  person Wesley Carlsen    schedule 03.06.2014
comment
strstr не подходит для использования с циклическими буферами - он не имеет представления о переносе.   -  person Sergey Kalinichenko    schedule 03.06.2014
comment
Однако я обрабатываю перенос с помощью локальных переменных: а именно головы и хвоста, которые увеличиваются и сбрасываются до 0, где это применимо   -  person Wesley Carlsen    schedule 03.06.2014
comment
Использование базового std::array для буфера и операций std::string, std::find() может работать лучше, чем использование strstr().   -  person πάντα ῥεῖ    schedule 03.06.2014
comment
@WesleyCarlsen Вы обрабатываете перенос, но strstr не обрабатывает его. Когда буфер заканчивается, и вы должны зациклиться, strstr продолжает двигаться вперед.   -  person Sergey Kalinichenko    schedule 03.06.2014
comment
@dasblinkenlight хорошо, как далеко это зайдет? нет параметра для длины буфера, так что strstr просто будет продолжаться до бесконечности? или пока он не достигнет нулевого символа?   -  person Wesley Carlsen    schedule 03.06.2014
comment
@WesleyCarlsen Когда strstr переходит конец буфера, это поведение undefined. Он будет продолжаться до тех пор, пока не найдет ноль, поэтому, скорее всего, он не рухнет.   -  person Sergey Kalinichenko    schedule 04.06.2014
comment
Раньше у меня были конечные данные. Я экспериментировал с использованием strlen(data)-strlen(end) и избавился от strlen перед публикацией здесь и забыл изменить порядок... мой плохой. Но на самом деле я видел проблему с большой разницей, когда это было конец - данные.   -  person Wesley Carlsen    schedule 04.06.2014
comment
Позвольте мне привести реальные цифры, чтобы сделать это более конкретным: start = 40002250, end = 4000228C, diff = 60073750608   -  person Wesley Carlsen    schedule 04.06.2014
comment
@WesleyCarlsen Это выглядит неправильно, потому что 4000228C-40002250 равно 3C (60 в десятичном формате).   -  person Sergey Kalinichenko    schedule 04.06.2014
comment
Правильно, поэтому я был так смущен. На самом деле я нашел эту страницу, на которой, по-видимому, говорится, что вы не можете выполнять арифметические операции с указателями: -указатель-арифметика   -  person Wesley Carlsen    schedule 04.06.2014
comment
@WesleyCarlsen, вы можете вычесть один указатель из другого, если они оба указывают на один и тот же буфер (или один за концом), как объясняется в верхнем ответе по этой ссылке. Ваши реальные цифры невозможны.   -  person M.M    schedule 04.06.2014


Ответы (1)


Вы не можете использовать strstr с кольцевым буфером, потому что он не знает, где обернуться. Рассмотрим этот макет буфера:

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

Ваша программа не сможет найти Hello, потому что его конец до его начала. Поэтому вам нужно написать свой собственный circ_strstr, который берет буфер вместе с его длиной в дополнение к начальной позиции и строке поиска.

У вашей программы тоже будут проблемы с линейным буфером, потому что она может найти \r\n из предыдущего токена. Начинать поиск закрывающего токена нужно с позиции после точки, где был найден начальный токен. В противном случае ваше end может быть меньше data, поэтому вычитание даст отрицательное число (которое будет интерпретировано как огромное беззнаковое значение).

person Sergey Kalinichenko    schedule 03.06.2014
comment
Хорошо, это логично, я не думал об этом вопросе. Спасибо! - person Wesley Carlsen; 04.06.2014
comment
Еще одна проблема с strstr: что, если многосимвольные маркеры пересекают точку перехода? Они могут никогда не быть найдены, потому что они не существуют в буфере. strstr с радостью пройдёт мимо конца буфера, потому что он не знает о зацикливании. - person David Hammen; 04.06.2014
comment
Так что, возможно, strstr() - неправильный способ сделать это. Может быть, мне нужно отказаться от этой идеи и вернуться к мозговому штурму - person Wesley Carlsen; 04.06.2014
comment
@WesleyCarlsen Вы можете написать свой собственный circ_strstr, который знает, что буфер является циклическим. Это не должно быть слишком сложно. - person Sergey Kalinichenko; 04.06.2014
comment
Истинный. Это может быть лучший подход - person Wesley Carlsen; 04.06.2014