The following is the most basic example I can come up with to pass variable-length args to a function:
int printme(int num, ...)
{
va_list ap;
va_start(ap, num);
for (int i = 0; i < num; ++i) {
char *arg = va_arg(ap, char *);
printf("%d. %s\n", i + 1, arg);
}
va_end(ap);
return 1;
}
int main(void)
{
printme(2, "X", "YY");
}
However, notice that I am passing in the length as the first argument (or as any argument). Is it possible to use these va_
macros with something like a printf
-ish function? For example, could I do something like this (without passing the number of args?
print2("Hello something %s %s", "Arg 1", "Arg 2");
print2("Hello something %s %s %s", "Arg 1", "Arg 2", "Arg 3");
If so, what would the function to receive that look like? And if it's not possible, how does printf
implement it then?
If you only want to pass strings, it can be done quite easily by writing a function to parse the first argument like countargs(char*)
that I've written here. It returns the number of arguments:
#include <stdarg.h>
#include <stdio.h>
int printme(char* fmt, ...)
{
va_list ap;
int num = countargs(fmt);
va_start(ap, num);
for (int i=0; i < num; ++i) {
char* arg = va_arg(ap, char*);
printf("%d. %s\n", i+1, arg);
}
va_end(ap);
return 1;
}
int countargs(char* fmt)
{
int i, num = 0;
if(strlen(fmt) < 2)
{
return 0;
}
for(i = 0; fmt[i+1] != '\0'; i++)
{
if (fmt[i] == '%' && fmt[i+1] == 's')
{
num++;
}
}
return num;
}
int main(void)
{
printme("%s%s", "Stack", "Overflow");
}
Here's a basic example of detecting the number of arguments from a parsed string. It's not taking into account any special circumstances and doesn't do anything with actually formatting/parsing the strings, but shows a basic working program to show how the count can be parsed from a string:
int printmy(char * format, ...)
{
// num args
int num = 0;
for(char idx=0, c; c=format[idx]; idx++) {
// ignore escape char + double-percent
if (c=='\\' || (c=='%' && format[idx+1]=='%'))
idx++;
else if (c=='%')
num++;
}
// print variable args
va_list ap;
va_start(ap, format); // need to give it the last argument before the "..."
for (int i=0; i < num; ++i) {
char* arg = va_arg(ap, char*);
printf("%d. %s\n", i+1, arg);
}
va_end(ap);
// return num args received
return num;
}
int main(void)
{
int num_args = printmy("Hello something \% \\% %% %s %s %s", "Arg 1", "Arg 2", "Arg 3");
printf("Num Args Parsed: %d\n", num_args);
}
And we get:
1. Arg 1
2. Arg 2
3. Arg 3
4.
Num Args Parsed: 4
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With