Список переменных snprintf не конвертирует enum в char *

0

Я выполняю задачу по изменению текущего механизма ведения журнала в моей кодовой базе CPP.

Текущий - это что-то вроде printf, в котором мы можем написать

MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));

Теперь, как часть его изменения к новому механизму ведения журнала, я хочу получить этот полный вывод в строку, используя snprintf(). Для этого я использовал список переменных для этого.

Код был похож

#define MYLOGGING(log_string,...) do { \
char buff[1024]; \
memset(buff, 0, sizeof(buff)); \
snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__); \
MYNEW_LOG(NewlogParams, buff); \
} while(0)

Теперь я столкнулся с проблемой. В существующем журнале было много экземпляров, в которых некоторые значения перечисления печатаются с использованием простого% d. В таких случаях с этим новым кодом он выдает следующую ошибку.

error: невозможно преобразовать 'enumType в' const char * для аргумента '3 в' int snprintf (char *, size_t, const char *,...)

Один очевидный вариант, чтобы избавиться от этого - дать целочисленный тип casting для распечаток enum.

Поскольку это может быть утомительным процессом, мне любопытно узнать, могу ли я исправить это каким-то другим способом?

Пожалуйста, поделитесь своими взглядами.

Заранее спасибо.

Теги:
variadic-functions
printf

1 ответ

2
Лучший ответ

__VA_ARGS__ оператор ## в __VA_ARGS__, вы превращаете параметры формата в const char *:

snprintf(buff, sizeof(buff), log_string, ##__VA_ARGS__);

Измените это на:

snprintf(buff, sizeof(buff), log_string, __VA_ARGS__);

и преобразование должно работать.


На самом деле, внимательно посмотрев на ваш вопрос, я заметил еще одну проблему. Оператор ## действительно необычен и, вероятно, неверен, однако главной причиной вашей проблемы, по-видимому, являются дополнительные парнеры в вызове MYLOGGING

MYLOGGING(("Example Log :%s, Example Num: %d", String, Number));

Если вы компилируете вызов этого макроса в GCC с флагом -E для вывода предварительно обработанного источника, вы получите эту строку, расширенную из макроса:

do { char buff[1024]; memset(buff, 0, sizeof(buff)); snprintf(buff, sizeof(buff), ("Example Log :%s, Example Num: %d", String, Number)); ....

Вы можете видеть, что () все еще там, перепутав вызов snprintf. Поэтому удалите оба ## в макросе и дополнительные парсеры на сайте вызова.

  • 0
    Спасибо, Гламперт. Все хорошо, когда я изменил его на snprintf (бафф, sizeof (бафф), "log_string", ## VA_ARGS ); Теперь у меня путаница, какая разница между моим старым кодом и кодом "" для log_string. Не могли бы вы дать ответ?
  • 0
    Прочитайте об операторе конкатенации токенов: gcc.gnu.org/onlinedocs/cpp/Concatenation.html

Ещё вопросы

Сообщество Overcoder
Наверх
Меню