Страница 1 из 1
Разбор строки, пришедшей от модема.
Добавлено: Сб янв 28, 2017 20:17:51
supercelt
Привет. Мк stm32ret6b модем siemens c35i, прога - Keil5. принял строку от модема. Запихнул в буфер Buffer[], выглядит так:

Формат заранее известен. Он такой как на картинке. Но надо учесть вдруг данные могут по дороге частично растеряться, хотя это вряд ли. Это я к тому, что я явно указывал начало копирования Buffer[20]. Вобщем нужно быстро и изящно выдернуть всё что между кавычек. И учесть, что например потерю символов (сдвиг индексов массива) и если есть там +7, то + отрезать.
Re: Разбор строки, пришедшей от модема.
Добавлено: Сб янв 28, 2017 20:30:34
ARV
не понимаю, как человек, способный на ARM принять строку из модема, может задавать такие вопросы?!

Re: Разбор строки, пришедшей от модема.
Добавлено: Сб янв 28, 2017 20:45:54
supercelt
наверное потому что просто не сталкивался с необходимостью дербанить строки
Re: Разбор строки, пришедшей от модема.
Добавлено: Сб янв 28, 2017 22:04:59
uk8amk
Начнём?
Код: Выделить всё
typedef struct
{
char *str;
char len;
} STR_RESULT;
STR_RESULT find_your_str( char *str, char len )
{
STR_RESULT result={0,0};
uint8_t i=0;
while( i<len )
{
if( str[i++] == '"' )
{
result.str = str+i-1; // start
break;
};
};
while( i<len )
{
if( str[i] == '+' )
{
result.str++;
};
if( str[i++] == '"' )
{
result.len = i; // stop
break;
};
};
return result;
}
Ну или посмотреть что там в string.h предлагают.
Re: Разбор строки, пришедшей от модема.
Добавлено: Сб янв 28, 2017 23:36:04
supercelt
в стрингах ничего особо-то и не предлагают. Ну я попробовал вот так:
Код: Выделить всё
void GSM_COMM_GET_SMS_SERVICE(){
char pattern_number[1] = "\"";
char *link_pattern_number = pattern_number;
char *number = strstr(Buffer_Receive, link_pattern_number);
//Указатель number указывает на первый символ ".
//Если далее записать вот так:
LCD_Send_String(1, number);
//То на экран выведется всё что после первых кавычек.
}
А как отловить вторые кавычки не знаю. Мне нужен индекс массива, что бы крутить его в цикле. А по указателю можно определить индекс элемента массива?
Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 00:55:28
uk8amk
Думается мне как-то так:
Код: Выделить всё
char *start=NULL, *stop=NULL;
int idx, len;
char *number = strstr(Buffer_Receive, link_pattern_number);
if( number != NULL )
{
number++;
start=number;
stop = strstr(++number, link_pattern_number);
if( stop != NULL )
{
stop--;
idx = start-Buffer_Receive;// индекс для входа в строку
len = stop-start;//длина строки в кавычках
/* здесь что-то сделать со строкой */
}
}
Добавлено after 3 minutes 13 seconds:
И как определить конец строки?
Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 00:59:17
просто КОТ
В самом примитивном случае. Просто защищая себя от потери пары байт вначале строки:
Код: Выделить всё
char Result[11]; int start = 0;
for(int i = 0; i < 21; i++) { if(Buffer[i] == 34) { start = i; break; } }
for(int j = 0; j < 11; j++) Result[j] = Buffer[j + start];
Три магических числа.
11 -- знаков в мобильном номере
34 -- ASCII код знака "
21 -- до этого момента однозначно должен был появиться знак "

Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 18:14:15
supercelt
11 -- знаков в мобильном номере
Не обязательно. Вдруг будет номер из какого-нибудь Уругвая))
Добавлено after 2 hours 41 minute 34 seconds:
Ещё вариант. Работает. Но пока без отсекания знака +. Годно?
Код: Выделить всё
void GSM_EXTRACT_NUMBER(char *str){
uint8_t start, i, j;
char number[] = "";
for(i = 0; i < 44; i++){
if(start){
if(str[i] == 0x22){
start = 0;
break;
}
number[j++] = str[i];
}
if(str[i] == 0x22){
start = 1;
}
}
LCD_Send_String(1, number);
}
Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 19:38:50
pcb
Без внешних либ, но не проверялось.
Код: Выделить всё
/* by pcb
**
*/
char i; //индекс в буфере
bool foundnum = false; //найдена строка?
for(i = o; i < rxStrLen; ++i){
if(buf[i]=='"'){
char idx = 0; //индекс в найденом номере
++i; //на первый символ после '"'
foundnum = true;
while(buf[i]!='"'){ //копируем до конца, пока не найдем '"'
numStr[idx] = buf[i];
++i;
++idx;
}
}
if(foundnum) break; //если номер найден, то прерываем цикл
}
Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 20:40:25
uk8amk
supercelt писал(а):Годно?
Нет.
char number[] = ""; --- выделяется статически.
Re: Разбор строки, пришедшей от модема.
Добавлено: Вс янв 29, 2017 21:32:53
supercelt
то есть надо так?
А чем плохо динамически?
Re: Разбор строки, пришедшей от модема.
Добавлено: Пн янв 30, 2017 10:54:14
uk8amk
Ничем не плохо.
Лишь за тем исключением, что динамическое выделение реализуется иными методами.
А то что там было написано вылезало за границы и возможно портило чужую область памяти. Пока прога маленькая или не полностью протестирована это можно не заметить.
Re: Разбор строки, пришедшей от модема.
Добавлено: Пт фев 03, 2017 17:20:39
supercelt
Слушайте, а если для интереса с регулярками поработать, для практики. Как их прикрутить к Keil? Где взять библиотеку для регулярок под Keil с мануалом?
Re: Разбор строки, пришедшей от модема.
Добавлено: Чт фев 23, 2017 09:54:49
hi-tower
Автор, откройте для себя конечные автоматы, разбор таких строк станет ясным и простым.