#1 2018-03-12 02:32:54

Olej
Участник
Из Харьков
Зарегистрирован: 2018-03-08
Сообщений: 234

форматирование символьных строк

Сделаю так:

...
uint32_t i = 1000;
double s = 1.2345;
char msg[ 40 ];
sprintf( msg, "%d => %8.2f", i, s );
Serial.println( msg ); 
...

Результатом будет:

1000 =>         ?

Получается, что sprintf() функция есть, форматы %d, %s и т.д. - успешно работают. А формат %f/%e - нет. Почему? Хотя в описании форматов для printf() из avr-libc эти форматы (%f/%e) есть.
Более того, формат %8.2f определил даже ширину позиции вывода (8), знак '?' отстоит на это число позиций (менял-проверял).
Как можно форматировать строки?

#2 2018-03-12 09:23:47

Olej
Участник
Из Харьков
Зарегистрирован: 2018-03-08
Сообщений: 234

Re: форматирование символьных строк

Olej пишет:

Получается, что sprintf() функция есть, форматы %d, %s и т.д. - успешно работают. А формат %f/%e - нет. Почему? Хотя в описании форматов для printf() из avr-libc эти форматы (%f/%e) есть.

Подсказали в другом месте, может кому пригодится:

sprintf искаропки не поддерживает форматный вывод с плавающей точкой. Используй dtostrf() или dtostre().

#3 2018-03-12 09:25:33

Olej
Участник
Из Харьков
Зарегистрирован: 2018-03-08
Сообщений: 234

Re: форматирование символьных строк

Olej пишет:

Подсказали в другом месте, может кому пригодится:

sprintf искаропки не поддерживает форматный вывод с плавающей точкой. Используй dtostrf() или dtostre().

Пример:

#include <alloca.h>

void setup() {
  Serial.begin( 9600 ); // устанавливаем последовательное соединение
}

void reply( boolean lng ) {
  unsigned long time = millis();
  char *msg = (char*)alloca( 80 );
  if( !lng )
    sprintf( msg, ".%lu", time % 1000 );
  else
    sprintf( msg, "%02lu:%02lu.%03lu", 
             ( time / 1000 ) / 60, 
             ( time / 1000 ) % 60, time % 1000 );
  Serial.println( msg ); 
}

void loop() {
  if( Serial.available() > 0 ) // есть доступные данные
    reply( '?' == Serial.read() );
  Serial.flush(); 
  delay( 300 ); 
}

Результат:

00:01.802
00:03.916
00:06.332
.450
.358
00:15.669
00:18.685
00:45.133
01:40.422

#4 2018-03-12 09:28:07

Olej
Участник
Из Харьков
Зарегистрирован: 2018-03-08
Сообщений: 234

Re: форматирование символьных строк

Olej пишет:

Подсказали в другом месте, может кому пригодится:

Но там же подсказали и гораздо интереснее:

Если printf Вам нужен только для вывода в поток (как в Вашем примере), то ещё удобнее делать это (выводить в поток) сразу, без запроса буфера. Например,

//	Эти три строки пишем в начале файла
#include <stdio.h>
static int serial_fputchar(const char ch, FILE *stream) { Serial.write(ch); return ch; }
static FILE *serial_stream = fdevopen(serial_fputchar, NULL);

void setup(void) { 
	stdout = serial_stream; // эта строка первая в setup
	//
	// А ТЕПЕРЬ ТУПО ПОЛЬЗУЕМСЯ printf
	//
	Serial.begin(115200);
	int a = 8;
	// Печатаем a в разных видах
	printf("a=%d, a=%02d, a=%04d, a=%05d, a=%06d\n", a, a, a, a, a);
}

void loop(void){}

Пользуйтесь! smile

#5 2018-03-26 21:21:23

Olej
Участник
Из Харьков
Зарегистрирован: 2018-03-08
Сообщений: 234

Re: форматирование символьных строк

Olej пишет:

Подсказали в другом месте, может кому пригодится:

sprintf искаропки не поддерживает форматный вывод с плавающей точкой. Используй dtostrf() или dtostre().

sprintf искаропки, как мне кажется после некоторых экспериментов с кодом, не поддерживает и формат %llu или %lld для uint64_t ... да и вообще компилятор странно себя ведёт с int64_t - но это нужно отдельно проверять.

#6 2018-03-30 14:15:50

Kaka
Участник
Зарегистрирован: 2018-03-21
Сообщений: 82

Re: форматирование символьных строк

Olej пишет:

там же подсказали и гораздо интереснее

А чё не сказал, что там же подсказали, что этот замечательный метод применим только если есть лишние полкило программной памяти? Самом по себе не страшно (если есть), но неплохо бы и сказать про это людям, прежде, чем предлагать "пользуйтесь".

Быстрое сообщение

Введите сообщение и нажмите Отправить

Подвал раздела