Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: sprintf от Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры
firstvald
во франклине (для работы с плав арифметикой не использую, но спецэффект видел) и в кейле сталкиваюсь с тем, что sprintf мусорит в строке после полезной части. при выводе плавающего числа со спецификатором f4.1 после полезной части кидается еще байт так 9 мусора. обычно обхожу это тем, что завожу большую строку с запасом, фактически для вывода плавающего числа по спецификатору f4.1 требуется строка длиной 24 байта (с некоторым запасом), но может быть кто- то нашел лечилку?


в порядке пожарного бубна

может кому срочно поможет, как посмотрю подробнее еще отпишусь. вроде бы мусор исчезает, если вызвать последовательно сначала sprintf без поля точности: sprintf(...,"%f",....) и сразу же еще раз, но уже как нам нужно sprintf(...,"%4.3f",...).
scifi
Что-то не верится, что в кейле может быть такой глюкавый sprintf.
firstvald
вот что увидел . детально как всегда нет времени.

стал использовать строку в которой формирую спецификатор. Это нужно когда скажем меняем число знаков после запятой и что-то такое.

CODE
unsigned char specif[8];
float in_val;
unsigned char out_line[16];

memset(out_line,0,sizeof(out_line));
memset(specif,0,sizeof(specif));

specif[0]='%';
specif[1]='4';
specif[2]='.';
specif[3]='2';
specif[4]='f';
specif[5]=0;//это очень важно
//строка должна оканчиваться нулем (там выше вся строка обнулена, но это подчеркивает обязательность нуля)


и используем это

CODE
sprintf(out_line,specif,in_val);


важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).
psL
А зачем все эти телодвижения с обнулением памяти и записью массива? По идее достаточно такого:
Код
char specif[] = "%4.2f";

ну или такого, слегка параноидального:
Код
const char specif[] = "%4.2f\0";

возможно у вас массивы заданы как локальные переменные (в стеке), либо каким-то образом повреждается сегмент статических данных.
Сергей Борщ
Цитата(psL @ Dec 7 2014, 12:35) *
По идее достаточно такого:
По идее достаточно прочитать документацию. Но это для слабых. Суровые русские мужики чешут правое ухо левой ногой, изобретая свой велосипед.
Код
int digits = 4;
int decimals = 2;
sprintf(out_line, "%*.*f", digits, decimals, in_val);

psL
Цитата(Сергей Борщ @ Dec 7 2014, 14:31) *
По идее достаточно прочитать документацию. Но это для слабых. Суровые русские мужики чешут правое ухо левой ногой, изобретая свой велосипед.
Код
int digits = 4;
int decimals = 2;
sprintf(out_line, "%*.*f", digits, decimals, in_val);

По идее изменение формата sprintf не спасет буфер от поломки
Сергей Борщ
Цитата(psL @ Dec 7 2014, 14:30) *
По идее изменение формата sprintf не спасет буфер от поломки

Буфер ломается по какой-то другой причине. А мой комментарий насчет суровых мужиков относился к
Цитата(firstvald @ Dec 7 2014, 12:10) *
стал использовать строку в которой формирую спецификатор. Это нужно когда скажем меняем число знаков после запятой и что-то такое.



scifi
Цитата(firstvald @ Dec 7 2014, 13:10) *
важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).

Танцы с бубном. Очевидно, что, скорее всего, кто-то ещё гадит в стеке.
Ну и товарищ Борщ уже написал, как это правильно делается :-)
jcxz
Цитата(firstvald @ Nov 19 2014, 05:07) *
во франклине (для работы с плав арифметикой не использую, но спецэффект видел) и в кейле сталкиваюсь с тем, что sprintf мусорит в строке

Возможно - у Вас элементарно переполняется стек.
Наблюдал на IAR+CortexM3 использование ~0.5кБ стека при вызове printf-функций.
firstvald
Цитата(jcxz @ Dec 7 2014, 22:40) *
Возможно - у Вас элементарно переполняется стек.
Наблюдал на IAR+CortexM3 использование ~0.5кБ стека при вызове printf-функций.

не простая функция и приглядывать надо при использовании. пользую в 51 процессоре. озу осталось байт 300. сомневаюсь, что использует стек в регистрах, но если народ знает в каком месте print sprintf творит свое черное дело, то милости просим высказаться.


ps вот как только я стал писать параноидально, ручками раскладывая каждый байтик - эффект исчез.

CODE
const char specif[] = "%4.2f\0";


неплохо, но на самом деле же писал что спецификатор надо в ряде случаев менять .

Цитата(psL @ Dec 7 2014, 16:30) *
По идее изменение формата sprintf не спасет буфер от поломки


CODE
sprintf(out_line, "%*.*f", digits, decimals, in_val);


вот это интересно
scifi
Цитата(firstvald @ Dec 8 2014, 20:19) *
Код
sprintf(out_line, "%*.*f", digits, decimals, in_val);

вот это интересно

Под столом :-)
"О, сколько нам открытий чудных..."
firstvald
Цитата(scifi @ Dec 8 2014, 22:08) *
Под столом :-)
"О, сколько нам открытий чудных..."

ну да. за 19 лет первый раз вижу такую запись. rolleyes.gif
пад сталом я смотрел - там нету
Сергей Борщ
Цитата(firstvald @ Dec 8 2014, 21:17) *
ну да. за 19 лет первый раз вижу такую запись. rolleyes.gif
А оно уже лет 40 в документации на язык C описано...
jcxz
Цитата(firstvald @ Dec 7 2014, 16:10) *
важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).

Так Вы что - в качестве 2-го аргумента sprintf передавали не завершающуюся нулём строку (ASCIIZ)????
Жесть.... wacko.gif
А чего-ж Вы тогда хотели от sprintf? Правильно он Вам память и разрушил....
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.