Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту


 
Опции темы
Непрочитано 08.12.2017, 00:16  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Работа с командами GSM под stm32f4 (массивы)

Всем привет) Укажите пожалуйста на ошибки. Код работает, но может что-то я делаю слишком не оптимизированно.
Суть в следующем:

Есть массив
Код:
char gsm_cusd_command[30] = "AT+CUSD=1,,15\r";
char *gsm_point_cusd_command = gsm_cusd_command;
Есть массив, который заполняется тем, что напечатают на матричной клаве
Код:
char gsm_ussd_balance_command[16] = "";
char *gsm_point_ussd_balance_command = gsm_ussd_balance_command;
когда напечатали команду проверки баланса, в массиве будет "*100#"

Далее по нажатию определённой кнопки, надо всё что в массиве поместить в исходный массив между запятыми.
Сначала я писал под конкретную задачу, но потом подумал, а вдруг мне надо будет где-нибудь ещё это сделать
с другим массивом. И решил универсалить ф-ию.
Вобщем в ф-ию передаются параметры: указатель на массив в который дописывать, размер этого массива, указатель на массив
в котором хранится напечатанная команда, 2 символа между которыми надо всё вырезать если что-то было и вставить новое.
То есть если там раньше было ,*2005#, к примеру, то это вырезаем и вставляем новое.

Код:
system_cut_and_insert_array(gsm_point_cusd_command  , 30, gsm_point_ussd_balance_command, ',', ',');
Алгоритм такой:
Сначала надо посчитать не превышает ли размер массива (30) новый массив после вставки новой строки.
Поэтому я прогоняю массив, слежу за символами и считаю. После этого проверяю, если превышает, то return
Далее всё что после 2 символа надо потом дописать в хвост. Поэтому я это копирую во временный массив tmp
Далее я стираю всё что после первого символа.
Далее я после первого символа вставляю новую подстроку.
А далее дописываю в хвост тот кусочек ,15\r

Код:
void system_cut_and_insert_array(char *source, const uint8_t size, char *insert, char s1, char s2){ 
	uint8_t count = 0, c = 0;
	char *point_insert = 0, *point_delete = 0;
	char *s = source;
	char tmp[size];
	char *t = tmp;
	while(*s){
		if(c){
			if(*s == s2) break;				
			count++;
		}
		if(*s == s1 && !c){
			c = 1;
			point_insert = s + 1;
			point_delete = point_insert;
		}
		s++;
	}
	if((strlen(source) - count + strlen(insert)) › size) return;
	while(*s){
		*t = *s;
		t++;
		s++;
	}
	while(*point_delete){
		*point_delete = 0;
		point_delete++;
	}
	while(*insert){
		*point_insert = *insert;
		point_insert++;
		insert++;
	}
	t = tmp;
	while(*t){
		*point_insert = *t;
		point_insert++;
		t++;
	}
}
Скажите? Это конечно сделано по прямолинейной логике. Но может есть какие-нибудь программерские финты, что бы делать это не так размажисто?
Реклама:
supercelt вне форума  
Непрочитано 08.12.2017, 07:56  
akegor
Гуру портала
 
Аватар для akegor
 
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 18,856
Сказал спасибо: 2,532
Сказали Спасибо 11,772 раз(а) в 5,896 сообщении(ях)
akegor на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

На мой взгляд, проще иметь строковые константы начала и конца строки, между которыми вставляется переменная часть. Выходная строка в этом случае формируется в буфере простой конкатенацией констант и переменной части.
Этот подход более универсальный, чем Ваш. Особенно, если учесть, что есть достаточно много АТ команд, в которых возможно несколько пустых полей, разделенных запятыми.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
akegor вне форума  
Непрочитано 08.12.2017, 09:50  
mike-y-k
Модератор
 
Регистрация: 04.08.2010
Адрес: Москва СЗАО
Сообщений: 11,246
Сказал спасибо: 11,165
Сказали Спасибо 3,854 раз(а) в 2,925 сообщении(ях)
mike-y-k на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

А передача последовательно префикса, команды и суффикса не будет сильно проще?
Три строки в подпрограмму…
Если очень нужно в одном поле, то sprintf 'префикс%sсуффикс'.
Распределение буфера можно и динамически - главное не забыть его освободить после использования .
__________________
rtfm forever должно быть основой для каждого. Альтернатива грустна, поскольку метод слепого щенка успешно работает при весьма малом числе вариантов…
mike-y-k вне форума  
Непрочитано 08.12.2017, 10:04  
Easyrider83
Гуру портала
 
Аватар для Easyrider83
 
Регистрация: 27.10.2008
Адрес: ЕС
Сообщений: 10,835
Сказал спасибо: 918
Сказали Спасибо 4,308 раз(а) в 2,573 сообщении(ях)
Easyrider83 на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Вся эта белиберда заменяется одной командой sprintf. А для буферов лучше использовать динамическое выделение памяти. Будет более гибко.
И команду strcpy почитайте из stdlib. Зачем городить огород, когда он уже есть?
Easyrider83 вне форума  
Сказали "Спасибо" Easyrider83
mike-y-k (08.12.2017)
Непрочитано 08.12.2017, 13:34  
Bill
Гражданин KAZUS.RU
 
Регистрация: 02.06.2003
Адрес: Челябинск
Сообщений: 545
Сказал спасибо: 10
Сказали Спасибо 339 раз(а) в 202 сообщении(ях)
Bill на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Сообщение от Easyrider83 Посмотреть сообщение
Вся эта белиберда заменяется одной командой sprintf. А для буферов лучше использовать динамическое выделение памяти. Будет более гибко.
И команду strcpy почитайте из stdlib. Зачем городить огород, когда он уже есть?
Вообще-то, есть стандартные библиотечные функции для работы со строкам: strlen, strstr, strcat, strcpy... Или нет?
Bill вне форума  
Непрочитано 08.12.2017, 17:36  
dgrishin
Почётный гражданин KAZUS.RU
 
Регистрация: 12.02.2013
Сообщений: 1,015
Сказал спасибо: 43
Сказали Спасибо 273 раз(а) в 214 сообщении(ях)
dgrishin на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Если исходить из концепции "чем проще - тем лучше" я бы сделал так...

char gsm_cusd_command[30] = "AT+CUSD=1,";

char* pGsm_point_ussd_balance_command = &char gsm_cusd_command[10];

// то есть место в памяти, где располагается '\0' строки "AT+CUSD=1," я присвоил
//новой переменной, куда будет ввод данных.
// а после окончания ввода в конец надо дописать ",15\r"
// такой алгоритм требует меньше манипуляций со строками
dgrishin вне форума  
Непрочитано 09.12.2017, 22:05  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Спасибо за ответы! Захотел проверить ещё одну идею,
Вот я создаю массив указателей
Код:
char *gsm_cusd_command[2] = {"AT+CUSD=1,",",15\r"};
Получается, что указатель gsm_cusd_command[0] будет указывать на строку AT+CUSD=1,
а gsm_cusd_command[1] на ,15\r
Как передать всё это в функцию одним параметром?
Если так: my_func(gsm_cusd_command){} на работает

void my_func(char *source){}

User\src\gsm.c(149): error: #167: argument of type "char **" is incompatible with parameter of type "char *"

Или только каждый передавать
Код:
my_func(gsm_cusd_command[0], gsm_cusd_command[1]){}
UPD

Сделал указатель на указатель

Код:
char *gsm_cusd_part_command[2] = {"AT+CUSD=1,",",15\r"};
char **gsm_point_cusd_command = gsm_cusd_part_command;
Для доступа к значениям делаю так:

Код:
void gsm_merge_command(char **source){
char s
s = *source[0]; - это например доступ к значению первого указателя и его значение 'A'
s = *source[1]; - это например доступ к значению второго указателя и его значение ','
Но почему существуют ещё какие-то лишние элементы?
*source[2] будет '@'
*source[3] будет 'e'

Хотя их же нет. Мне просто надо каким-то образом из char **source в ф-ии сосчитать сколько там массивов с указателями. В данном случае должно получиться 2.

Последний раз редактировалось supercelt; 09.12.2017 в 23:58.
supercelt вне форума  
Непрочитано 10.12.2017, 10:09  
dgrishin
Почётный гражданин KAZUS.RU
 
Регистрация: 12.02.2013
Сообщений: 1,015
Сказал спасибо: 43
Сказали Спасибо 273 раз(а) в 214 сообщении(ях)
dgrishin на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Сообщение от supercelt Посмотреть сообщение
Но почему существуют ещё какие-то лишние элементы?
*source[2] будет '@'
*source[3] будет 'e'
Они совсем даже не лишние - вам ничего не мешает обратится по любому offset в массиве.
Если вам хочется красивое и универсальное решение - это можно сделать через классы (CPP). Создаётся класс STRING, в нём перегружается левая и правая операция '+' и вы сможете складывать элементы классов а также классов и строк как простые числа (для строк под '+' понимается конечно конкатенация).
Тогда весь ваш код будет выглядеть приблизительно так:

STRING Tail("AT+CUSD=1,");
STRING End(",15\r");
char gsm_ussd_balance_command; // здесь ввод пользователя
STRING Result();
Result = Tail + char gsm_ussd_balance_command;
Result = Result + End;
char* Output = Result.Get(); //Get() - ещё один метод класса STRING.

Такой пример со строками есть в любом учебнике по CPP

Последний раз редактировалось dgrishin; 10.12.2017 в 10:13.
dgrishin вне форума  
Непрочитано 10.12.2017, 15:41  
supercelt
Прописка
 
Регистрация: 29.03.2007
Сообщений: 185
Сказал спасибо: 11
Сказали Спасибо 1 раз в 1 сообщении
supercelt на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

Сообщение от dgrishin Посмотреть сообщение
Они совсем даже не лишние
Как не лишние, если этих индексов я не создавал?)

Код:
char *gsm_cusd_command[2] = {"AT+CUSD=1,",",15\r"};
Вот, их же только два, с индексами 0 и 1.
supercelt вне форума  
Непрочитано 10.12.2017, 16:31  
H4LF
Вид на жительство
 
Аватар для H4LF
 
Регистрация: 10.06.2007
Сообщений: 429
Сказал спасибо: 34
Сказали Спасибо 51 раз(а) в 47 сообщении(ях)
H4LF на пути к лучшему
По умолчанию Re: Работа с командами GSM под stm32f4 (массивы)

supercelt, Вы на чём пишете? Как думаете - там есть проверка границ массивов? В C об этом должен заботиться программист.
H4LF вне форума  
 

Закладки
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ностальжи по школе... Ar-Gen-Tum Отвлекитесь, эмбеддеры! 141 27.02.2015 16:10
GSM команды, работа из МК greafuger Микроконтроллеры, АЦП, память и т.д 2 05.04.2008 23:11
работа с GPRS в GSM модуле yel Автоматика и аппаратура связи 6 03.04.2007 13:38


Часовой пояс GMT +4, время: 14:33.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot