Особенно учитывая, что вы не упомянули, сколько параметров вы ожидаете, я бы просто сделал это динамически:
#include <stdarg.h>
#include <stdio.h>
int sprintf_vparams(char *Buf, int N /*number of int params*/, ...)
{
//no bufsize checking
va_list ap; va_start(ap,N);
char *buf = Buf;
buf += sprintf(buf,"Params: ");
for(int i=0; i<N; i++) buf += sprintf(buf,"\tparam_%d: %d", i+1, va_arg(ap,int));
va_end(ap);
return buf-Buf;
}
Функция не самая маленькая (186B на x86-64 с проверками переполнения буфераотключено), но вам не нужно будет генерировать статические строки уникального формата на сайтах вызовов + сайты вызовов будут такими же большими или чуть меньше, чем вы получили бы, если бы использовали sprintf
напрямую.
Если вы можете разумно ожидать, что число ваших параметров будет меньше определенного числа, вы можете использовать встроенный переключатель:
static inline int sprintf_aparams(char *Buf, int N /*number of int params*/, int X[])
{
#define P(Num) "\tparam_" #Num ": %d"
switch(N){
case 0: return sprintf(Buf,"Params: ");
case 1: return sprintf(Buf,"Params: " P(1), X[0]);
case 2: return sprintf(Buf,"Params: " P(1) P(2), X[0], X[1]);
case 3: return sprintf(Buf,"Params: " P(1) P(2) P(3), X[0], X[1], X[2]);
case 4: return sprintf(Buf,"Params: " P(1) P(2) P(3) P(4), X[0], X[1], X[2], X[3]);
case 5: return sprintf(Buf,"Params: " P(1) P(2) P(3) P(4) P(5), X[0], X[1], X[2], X[3], X[4]);
case 6: return sprintf(Buf,"Params: " P(1) P(2) P(3) P(4) P(5) P(6), X[0], X[1], X[2], X[3], X[4], X[5]);
default: abort(); /*not supported*/ return 0;
}
#undef P
}
#define MC_sprintf_params(Buf,...) sprintf_aparams(Buf, sizeof((int[]){__VA_ARGS__ })/sizeof(int), (int[]){__VA_ARGS__})
//usage:
int main()
{
char buf[1024];
MC_sprintf_params(buf,2,4,6,8,10,12); //print 6 params
}
Это будет абстракция с истинной нулевой стоимостью на современном компиляторе, таком как gcc или clang.