362 Stimmen

Übergabe einer variablen Anzahl von Argumenten

Angenommen, ich habe eine C-Funktion, die eine variable Anzahl von Argumenten annimmt: Wie kann ich eine andere Funktion aufrufen, die eine variable Anzahl von Argumenten erwartet, und dabei alle Argumente übergeben, die in die erste Funktion eingegangen sind?

Beispiel:

void format_string(char *fmt, ...);

void debug_print(int dbg_lvl, char *fmt, ...) {
    format_string(fmt, /* how do I pass all the arguments from '...'? */);
    fprintf(stdout, fmt);
 }

231voto

SmacL Punkte 22014

Um die Ellipsen weiterzugeben, initialisieren Sie eine va_list wie gewohnt und übergeben Sie es einfach an Ihre zweite Funktion. Sie verwenden nicht va_arg() . Konkret;

void format_string(char *fmt,va_list argptr, char *formatted_string);

void debug_print(int dbg_lvl, char *fmt, ...) 
{    
 char formatted_string[MAX_FMT_SIZE];

 va_list argptr;
 va_start(argptr,fmt);
 format_string(fmt, argptr, formatted_string);
 va_end(argptr);
 fprintf(stdout, "%s",formatted_string);
}

63voto

Es gibt keine Möglichkeit, (z.B.) printf aufzurufen, ohne zu wissen, wie viele Argumente man übergibt, es sei denn, man will sich auf unanständige und nicht portierbare Tricks einlassen.

Die allgemein verwendete Lösung besteht darin, immer eine alternative Form von vararg-Funktionen anzubieten, also printf hat vprintf die eine va_list anstelle der ... . Die ... Versionen sind nur Umhüllungen für die va_list Versionen.

53voto

Rose Perrone Punkte 58235

Variadische Funktionen kann sein gefährlich . Hier ist ein sicherer Trick:

   void func(type* values) {
        while(*values) {
            x = *values++;
            /* do whatever with x */
        }
    }

func((type[]){val1,val2,val3,val4,0});

30voto

user2023370 Punkte 9967

Im großartigen C++11 konnten Sie variadische Vorlagen verwenden:

template <typename... Ts>
void format_string(char *fmt, Ts ... ts) {}

template <typename... Ts>
void debug_print(int dbg_lvl, char *fmt, Ts... ts)
{
  format_string(fmt, ts...);
}

11voto

VarunG Punkte 106

Obwohl Sie lösen können, indem Sie den Formatierer in lokalen Puffer zuerst speichern, aber das braucht Stack und kann manchmal Problem zu behandeln. Ich habe folgendes versucht und es scheint gut zu funktionieren.

#include <stdarg.h>
#include <stdio.h>

void print(char const* fmt, ...)
{
    va_list arg;
    va_start(arg, fmt);
    vprintf(fmt, arg);
    va_end(arg);
}

void printFormatted(char const* fmt, va_list arg)
{
    vprintf(fmt, arg);
}

void showLog(int mdl, char const* type, ...)
{
    print("\nMDL: %d, TYPE: %s", mdl, type);

    va_list arg;
    va_start(arg, type);
    char const* fmt = va_arg(arg, char const*);
    printFormatted(fmt, arg);
    va_end(arg);
}

int main() 
{
    int x = 3, y = 6;
    showLog(1, "INF, ", "Value = %d, %d Looks Good! %s", x, y, "Infact Awesome!!");
    showLog(1, "ERR");
}

Ich hoffe, das hilft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X