This isn't a great idea to begin with, it will be super-vulnerable to all manner of exploits, typos and bugs. But if you insist, you could do a dirty hack as follows:
Assuming the format string in argv[1] is %s %s %s, then each we can divide this string length by 3 to get the number of strings. Save for the final one, which isn't followed by a trailing space. So strlen(argv[1]) + 1 then divide by 3:
#define STR_N ((strlen(argv[1])+1)/3)
Next up we can take advantage of printf ignoring trailing arguments not corresponding to the format string. So we could do printf(argv[1], argv[2], argv[3]); just fine without actually passing that many arguments, long as the format string contains the correct amount of conversion specifiers. For example:
#define ARGV_LIST \
argv[2],\
argv[3],\
argv[4],\
argv[5],\
argv[6],\
argv[7],\
argv[8],\
argv[9]\
printf(argv[1], ARGV_LIST);
Then cook up something to convert the indices and make sure that array out of bounds never occurs:
#include <stdio.h>
#include <string.h>
#define STR_N ((strlen(argv[1])+1)/3)
#define INDEX(n) (STR_N>n? (n+2) : 0)
#define ARGV_LIST \
argv[INDEX(0)],\
argv[INDEX(1)],\
argv[INDEX(2)],\
argv[INDEX(3)],\
argv[INDEX(4)],\
argv[INDEX(5)],\
argv[INDEX(6)],\
argv[INDEX(7)],\
argv[INDEX(8)],\
argv[INDEX(9)]\
int main(int argc, char *argv[])
{
printf(argv[1], ARGV_LIST);
return 0;
}
Tested in Windows with prog.exe "%s %s %s %s %s" hello this is a test gives output:
hello this is a test
printf, so you have to parse the format string yourself. The linked code is an example.