Reputation: 20644
if I have this function:
printAll(const char *message, ...)
{
va_list argptr = NULL;
va_start(argptr, message);
// todo: how to printf all the arguments in the message?
va_end(argptr);
}
Suppose I call the function like this:
printAll("My info: Value1 = %d, Value 2=%d", 1, 2);
In this line: // todo: how to printf all the arguments in the message?
How can I print them all in order to have:
My info: Value1 = 1, Value 2=2
Upvotes: 3
Views: 6225
Reputation: 79
Here is a printAll() that will do exactly as you would like...
#ifdef __cplusplus
#include <cstring>
#include <cstdio>
#include <cstdarg>
using namespace std;
#else
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#endif
void printAll(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
const size_t MAX_LEN = 1023;
#ifdef __cplusplus
char msg[MAX_LEN+1] = {0};
#else
char msg[MAX_LEN+1];
for (int i = 0; i < MAX_LEN+1; i++)
{
msg[i] = 0;
}
#endif
vsnprintf(msg, MAX_LEN, fmt, ap);
printf("%s\n", msg);
va_end(ap);
}
int main() {
printAll("My info: Value1 = %d, Value 2=%d", 1, 2);
return 0;
}
My info: Value1 = 1, Value 2=2
Upvotes: 1
Reputation: 490108
Here's a sketch of the general idea (though a finished version, has to deal with quite a few more things such as field width, precision, more conversions, etc.
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
int my_vfprintf(FILE *file, char const *fmt, va_list arg) {
int int_temp;
char char_temp;
char *string_temp;
char ch;
int length = 0;
char buffer[512];
while ( ch = *fmt++) {
if ( '%' == ch ) {
switch (ch = *fmt++) {
/* %% - print out a single % */
case '%':
fputc('%', file);
length++;
break;
/* %c: print out a character */
case 'c':
char_temp = va_arg(arg, int);
fputc(char_temp, file);
length++;
break;
/* %s: print out a string */
case 's':
string_temp = va_arg(arg, char *);
fputs(string_temp, file);
length += strlen(string_temp);
break;
/* %d: print out an int */
case 'd':
int_temp = va_arg(arg, int);
itoa(int_temp, buffer, 10);
fputs(buffer, file);
length += strlen(buffer);
break;
/* %x: print out an int in hex */
case 'x':
int_temp = va_arg(arg, int);
itoa(int_temp, buffer, 16);
fputs(buffer, file);
length += strlen(buffer);
break;
}
}
else {
putc(ch, file);
length++;
}
}
return length;
}
int my_printf(char const *fmt, ...) {
va_list arg;
int length;
va_start(arg, fmt);
length = my_vfprintf(stdout, fmt, arg);
va_end(arg);
return length;
}
int my_fprintf(FILE *file, char const *fmt, ...) {
va_list arg;
int length;
va_start(arg, fmt);
length = my_vfprintf(file, fmt, arg);
va_end(arg);
return length;
}
#ifdef TEST
int main() {
my_printf("%s", "Some string");
return 0;
}
#endif
Upvotes: 1
Reputation: 54551
You're looking for the vprintf()
function which was designed to do exactly this:
vprintf(message, argptr);
The v*printf()
family of functions work basically in the same way as their normal counterparts, except they take a va_list instead of varargs. They don't call va_end()
for you, so the way you have it now is correct.
Upvotes: 15