Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Переменное число аргументов, почему так не работает? / 10 сообщений из 10, страница 1 из 1
23.10.2018, 15:01
    #39721483
vvvait
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
есть процедура:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
void debugMsg(const char * format, ...) {
  Serial.print(millis());
  Serial.print('[');
  Serial.print(ESP.getFreeHeap());
  Serial.print("] ");  
  va_list arg;  
  va_start(arg, format);  
  Serial.printf(format, arg); 
/*
  char temp[64];
  char* buffer = temp;
  size_t len = vsnprintf(temp, sizeof(temp), format, arg);
  va_end(arg);
  if (len > sizeof(temp) - 1) {
      buffer = new char[len + 1];
      if (!buffer) {
          return;
      }
      va_start(arg, format);
      vsnprintf(buffer, len + 1, format, arg);
      va_end(arg);
  }
  len = Serial.write((const uint8_t*) buffer, len);
  if (buffer != temp) {
    delete[] buffer;
  } 
*/
  Serial.println("");  
  va_end(arg);
}



процедура в таком виде не выводит текст из параметров,
если закомментировать Serial.printf(format, arg), а остальное раскомментировать, то выводит.
Закомментированный кусок это содержимое Print::printf

Как сделать правильно чтобы не писать весь код printf?
...
Рейтинг: 0 / 0
23.10.2018, 15:20
    #39721499
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
vvvait
Код: plaintext
1.
2.
3.
  va_list arg;  
  va_start(arg, format);  
  Serial.printf(format, arg);



Все правильно, это не должно работать, т.к. Serial.printf() вторым аргументом врядли поддерживает значения типа va_list.

Вам нужен второй вариант этой функции - Serial.vprintf который бы принимал va_list, и потом например печатал его через vsnprintf или аналоги.
...
Рейтинг: 0 / 0
23.10.2018, 15:48
    #39721519
vvvait
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
спасибо, я думал что va_list передаётся как эти три точки
к сожалению у этого Serial нет функции vprintf
...
Рейтинг: 0 / 0
23.10.2018, 16:19
    #39721533
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
vvvait,

Если у вас С++ 11 и выше, то можно обойтись вообще без va_list.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
template<typename ...Args>
void debugMsg(const char * format, Args ... args) {
  Serial.print(millis());
  Serial.print('[');
  Serial.print(ESP.getFreeHeap());
  Serial.print("] ");  
  Serial.printf(format, args...); 
  Serial.println("");  
}


Тогда текущая версия Serial.printf подойдет без изменений.
...
Рейтинг: 0 / 0
23.10.2018, 17:32
    #39721585
ну я
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
vvvait,

Можно выполнить vsprintf в буфер и передать через
Serial.printf("%s", buf);
...
Рейтинг: 0 / 0
24.10.2018, 13:07
    #39722042
vvvait
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
Anatoly Moskovsky, спасибо, именно этого и хотелось
...
Рейтинг: 0 / 0
24.10.2018, 13:11
    #39722050
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
Anatoly MoskovskyЕсли у вас С++ 11 и выше, то можно обойтись вообще без va_list.

С макросом это было бы короче:
Код: sql
1.
2.
#define debugMsg(format, ...) Serial.printf("%d[%d] " format, millis(), 
ESP.getFreeHeap(), VA_ARGS)


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
24.10.2018, 14:26
    #39722136
OoCc
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
Dimitry SibiryakovAnatoly MoskovskyЕсли у вас С++ 11 и выше, то можно обойтись вообще без va_list.

С макросом это было бы короче:
Код: sql
1.
2.
#define debugMsg(format, ...) Serial.printf("%d[%d] " format, millis(), 
ESP.getFreeHeap(), VA_ARGS)



Макрос должен быть поскольку это отладочные сообщения. Если мы говорим о С++ то я бы использовал оператор <<
что то типа такого
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
#define  debugMsg(ARGS)  \
do { \
   std::string buff; buff.reserve(128);
   std::ostringstream os(buff); \
   os << std::setw(10) <<  millis() \
      << " ["<< std::setfill('0') << std::hex << std::setw(10) << ESP.getFreeHeap() << "] "  << std::setfill(' ') << std::dec \
      << ARGS; \
   Serial.puts(os.str().c_str()); \
} while(0);

main()
{
...............

debugMsg( var1 << " " << var2 << " etc..." )


ещё один нюанс для ТС - отладочное сообщение в порт лучше выводить одной строкой чтобы не вклинивались сообщения из других нитей.
...
Рейтинг: 0 / 0
24.10.2018, 15:20
    #39722213
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
Dimitry SibiryakovС макросом это было бы короче:
Не будет работать для пустого списка аргументов.
...
Рейтинг: 0 / 0
24.10.2018, 16:17
    #39722282
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Переменное число аргументов, почему так не работает?
Anatoly MoskovskyНе будет работать для пустого списка аргументов.

Для GNU CPP - будет: https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Переменное число аргументов, почему так не работает? / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]