Перейти к содержанию
    

sprintf от Keil

во франклине (для работы с плав арифметикой не использую, но спецэффект видел) и в кейле сталкиваюсь с тем, что sprintf мусорит в строке после полезной части. при выводе плавающего числа со спецификатором f4.1 после полезной части кидается еще байт так 9 мусора. обычно обхожу это тем, что завожу большую строку с запасом, фактически для вывода плавающего числа по спецификатору f4.1 требуется строка длиной 24 байта (с некоторым запасом), но может быть кто- то нашел лечилку?

 

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вот что увидел . детально как всегда нет времени.

 

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

 

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;//это очень важно
//строка должна оканчиваться нулем (там выше вся строка обнулена, но это подчеркивает обязательность нуля)

 

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

 

sprintf(out_line,specif,in_val);

 

важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем все эти телодвижения с обнулением памяти и записью массива? По идее достаточно такого:

char specif[] = "%4.2f";

ну или такого, слегка параноидального:

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

возможно у вас массивы заданы как локальные переменные (в стеке), либо каким-то образом повреждается сегмент статических данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По идее достаточно такого:
По идее достаточно прочитать документацию. Но это для слабых. Суровые русские мужики чешут правое ухо левой ногой, изобретая свой велосипед.

int digits = 4;
int decimals = 2;
sprintf(out_line, "%*.*f", digits, decimals, in_val);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По идее достаточно прочитать документацию. Но это для слабых. Суровые русские мужики чешут правое ухо левой ногой, изобретая свой велосипед.

int digits = 4;
int decimals = 2;
sprintf(out_line, "%*.*f", digits, decimals, in_val);

По идее изменение формата sprintf не спасет буфер от поломки

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По идее изменение формата sprintf не спасет буфер от поломки

Буфер ломается по какой-то другой причине. А мой комментарий насчет суровых мужиков относился к

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

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).

Танцы с бубном. Очевидно, что, скорее всего, кто-то ещё гадит в стеке.

Ну и товарищ Борщ уже написал, как это правильно делается :-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

во франклине (для работы с плав арифметикой не использую, но спецэффект видел) и в кейле сталкиваюсь с тем, что sprintf мусорит в строке

Возможно - у Вас элементарно переполняется стек.

Наблюдал на IAR+CortexM3 использование ~0.5кБ стека при вызове printf-функций.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно - у Вас элементарно переполняется стек.

Наблюдал на IAR+CortexM3 использование ~0.5кБ стека при вызове printf-функций.

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

 

 

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

 

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

 

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

 

По идее изменение формата sprintf не спасет буфер от поломки

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Под столом :-)

"О, сколько нам открытий чудных..."

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Под столом :-)

"О, сколько нам открытий чудных..."

ну да. за 19 лет первый раз вижу такую запись. :rolleyes:

пад сталом я смотрел - там нету

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну да. за 19 лет первый раз вижу такую запись. :rolleyes:
А оно уже лет 40 в документации на язык C описано...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

важно, чтобы в строке , в которой записывается спецификация, после полезной части был обязательно 0. Собственно, это определение строки. Если нуля нет , то результат будет как я описывал изначально: мусор на неопределенную глубину , причем, результат изменяется от запуска к запуску (собственно программа пошла гулять по озу пока не нарвется на 0).

Так Вы что - в качестве 2-го аргумента sprintf передавали не завершающуюся нулём строку (ASCIIZ)????

Жесть.... :wacko:

А чего-ж Вы тогда хотели от sprintf? Правильно он Вам память и разрушил....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...