Функция Variadic не передает первый аргумент правильно - PullRequest
1 голос
/ 12 апреля 2019

Я использовал переменные функции для переноса printf (или vprintf).

Следующий код работает, за исключением ошибки в первом аргументе переменной warning_printf.Кроме того, непосредственное размещение строки изменит символ ASCII, но не исправит его, поскольку сообщение все еще случайное.

Печатается

[Warning]
          ®¯$ address: 0x87afae8a

Вместо

[Warning] Failed to initialize setting address: 0x87afae8a

Там, где слово «Предупреждение» окрашено правильно (в любом случае это не имеет значения).Но msg_warn, кажется, передается неправильно.Я протестировал добавление дополнительных переменных к этой функции.Все они работают нормально, за исключением только первого переменного аргумента msg_warn.

Что не так с моим кодом?

void colorful_printf( const char* header, const char* color, const char* fmt, ... )
{
    printf("[%s%s%s] ", color, header, RESET_ANSI_COLOR);
    va_list args;
    va_start( args, fmt );
    vprintf(fmt, args);
    va_end( args );
}


void warning_printf( const char* fmt, ... )
{
    va_list args;
    va_start( args, fmt );
    colorful_printf("Warning", WARNING_COLOR, fmt, args);
    va_end( args );
}


char msg_warn[] = "Failed to initialize setting";
warning_printf( "%s address: 0x%2x", msg_warn, address );

Онлайн-компилятор: ссылка

1 Ответ

2 голосов
/ 12 апреля 2019

Вам необходимо передать va_list функции, которая ожидает их - аналог функций v*printf().

void colorful_vprintf(const char* header, const char* color, const char* fmt, va_list args)
{
    printf("[%s%s%s] ", color, header, RESET_ANSI_COLOR);
    vprintf(fmt, args);
}

void colorful_printf(const char* header, const char* color, const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    colorful_vprintf(header, color, fmt, args);
    va_end(args);
}

void warning_vprintf(const char* fmt, va_list args)
{
    colorful_vprintf("Warning", WARNING_COLOR, fmt, args);
}

void warning_printf(const char* fmt, ...)
{
    va_list args;
    va_start(args, fmt);
    warning_vprintf(fmt, args);
    va_end(args);
}

Функции *_vprintf выполняют реальную работу;функции, имеющие многоточие, просто получают va_list для аргументов и передают их в функции *_vprintf().Это общий шаблон для интерфейсов (оберток вокруг) семейства функций printf().

...