Учитывая, что va_arg
должен вызываться в правильном порядке и с правильным типом для правильного поведения, я думаю, что вам нужно потреблять fmt
по частям, обрабатывая части, которые вам нужны, и передавая оставшуюся часть vsprintf
:
void
mysprintf(char *dst, char *fmt, ...)
{
char *p = fmt;
va_list va;
va_start(va, fmt);
do {
char *q = strchr(p, '|');
if (q) {
/* really should take const char *fmt and not write on it like this... */
*q++ = '\0';
}
dst += vsprintf(dst, p, va); /* let vsprintf do a subset */
if (q) {
dst += sprintf(dst, "%d", va_arg(va, int)); /* consume 1 int */
}
p = q;
} while (p);
va_end(va);
}
strcpy(fmt, "%s|%s|%s"); /* mutable fmt */
mysprintf(buf, fmt, "hello", 7, "world", 8, "!");
В моем примере я просто взял |
, чтобы быть похожим на %d
, но реальный пример с дополнительными %...
побегами будет намного более сложным.