Разбор строки, пришедшей от модема.

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

Привет. Мк stm32ret6b модем siemens c35i, прога - Keil5. принял строку от модема. Запихнул в буфер Buffer[], выглядит так:
Изображение
Формат заранее известен. Он такой как на картинке. Но надо учесть вдруг данные могут по дороге частично растеряться, хотя это вряд ли. Это я к тому, что я явно указывал начало копирования Buffer[20]. Вобщем нужно быстро и изящно выдернуть всё что между кавычек. И учесть, что например потерю символов (сдвиг индексов массива) и если есть там +7, то + отрезать.
Реклама
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

не понимаю, как человек, способный на ARM принять строку из модема, может задавать такие вопросы?! :shock:
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

наверное потому что просто не сталкивался с необходимостью дербанить строки
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение 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 предлагают.
Реклама
Эиком - электронные компоненты и радиодетали
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение 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);
				//То на экран выведется всё что после первых кавычек. 
}

А как отловить вторые кавычки не знаю. Мне нужен индекс массива, что бы крутить его в цикле. А по указателю можно определить индекс элемента массива?
Реклама
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение 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:
supercelt писал(а):

Код: Выделить всё

				char pattern_number[1] = "\"";
}
И как определить конец строки?
Реклама
Друг Кота
Аватара пользователя
Сообщения: 12364
Зарегистрирован: Пт дек 17, 2010 15:07:50
Откуда: Крымский Федеральный Округ

Сообщение просто КОТ »

В самом примитивном случае. Просто защищая себя от потери пары байт вначале строки:

Код: Выделить всё

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 -- до этого момента однозначно должен был появиться знак " :write:
Изображение
И ты врёшь!!! © Vladisman
Изображение
Контактная информация:
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение 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);
}
pcb
Опытный кот
Сообщения: 833
Зарегистрирован: Пт авг 12, 2011 09:14:27
Откуда: Млечный путь/Земля/РФ/Екатеринбург

Сообщение 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;			//если номер найден, то прерываем цикл
}

Разработал:
-BLDC
-ФУОЗ/МПСЗ
-SMART BMS
-ECU/EDC на STM32F4(43%)+CPLD(57%)
-Моноинжектор на ATSAMD20G16
-контроллер эффектов для RGB LED ленты
-умные часы/обратный счет/секундомер
-устройство измерения емкости АКБ
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

supercelt писал(а):Годно?
Нет.

char number[] = ""; --- выделяется статически.
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

то есть надо так?

Код: Выделить всё

char number[11];
А чем плохо динамически?
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Ничем не плохо.
Лишь за тем исключением, что динамическое выделение реализуется иными методами.
А то что там было написано вылезало за границы и возможно портило чужую область памяти. Пока прога маленькая или не полностью протестирована это можно не заметить.
Открыл глаза
Сообщения: 68
Зарегистрирован: Вс авг 02, 2015 18:02:38

Сообщение supercelt »

Слушайте, а если для интереса с регулярками поработать, для практики. Как их прикрутить к Keil? Где взять библиотеку для регулярок под Keil с мануалом?
Родился
Сообщения: 1
Зарегистрирован: Чт фев 23, 2017 09:52:10

Сообщение hi-tower »

Автор, откройте для себя конечные автоматы, разбор таких строк станет ясным и простым.
Ответить

Вернуться в «ARM»