16

So, here's a small problem I'm facing right now -> I'm trying to write a function that will accept a char* message and a variable number of arguments. My function will modify the message a little, and then It'll call printf with the message and given parameters. Essentialy, I'm trying to write something like that:

void modifyAndPrintMessage(char* message,...){
    char* newMessage; //copy message.
    //Here I'm modifying the newMessage to be printed,and then I'd like to print it. 
    //passed args won't be changed in any way.

    printf(newMessage,...); //Of course, this won't work. Any ideas?
    fflush(stdout);

}

So, anybody knows what should I do to make it happen? I'd be most grateful for any help :)

JJS
  • 1,086
  • 2
  • 13
  • 16
  • http://bobobobo.wordpress.com/2008/01/28/how-to-use-variable-argument-lists-va_list/ – frickskit Apr 05 '13 at 14:30
  • This is not really a duplicate of [SO 15830641](http://stackoverflow.com/q/15830641), nor of [SO 15836392](http://stackoverflow.com/q/15836392) which the other is closed as a duplicate of. – Jonathan Leffler Apr 05 '13 at 22:35

5 Answers5

17

You want to use varargs...

void modifyAndPrintMessage( char* message, ... )
{
    // do somehthing custom

    va_list args;
    va_start( args, message );

    vprintf( newMessage, args );

    va_end( args );
}
K Scott Piel
  • 4,320
  • 14
  • 19
4
void modifyAndPrintMessage(char* message,...)
{   char newMessage[1024]; // **Make sure the buffer is large enough**
    va_list args;
    va_start(args, message);
    vsnprintf(newMessage, message, args);
    printf(newMessage);
    fflush(stdout);
}
Edward Clements
  • 5,040
  • 2
  • 21
  • 27
  • K Scott Piel gave an even simpler way of doing this, by using vprintf instead of vsnprintf, but your way is also good and clean. Thank you! – JJS Apr 05 '13 at 14:41
  • yes, but in that case shouldn't the code be something like `va_start(args, message);` followed by `vprintf(message, args);`? – Edward Clements Apr 05 '13 at 14:46
  • 1. `printf("%s", newMessage)` - Otherwise you expand `%` twice. 2. `newMessage[sizeof(newMessage)-1] = '\0'` will assure termination (so long messages will be just truncated). – ugoren Aug 29 '13 at 08:37
  • And you need `va_end`. On most platforms it does nothing, but still needed. – ugoren Aug 29 '13 at 08:40
0

Use varargs to accept variable number of parameters then use sprintf to create the new message

msam
  • 4,259
  • 3
  • 19
  • 32
0

You can use va_list from stdarg.h,

C example: http://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm C++ example: http://www.cprogramming.com/tutorial/lesson17.html.

An of course, see the man page: http://linux.die.net/man/3/stdarg

Man page example for reference:

#include <stdio.h>

#include <stdarg.h>

void
foo(char *fmt, ...)
{
    va_list ap;
    int d;
    char c, *s;

   va_start(ap, fmt);
    while (*fmt)
        switch (*fmt++) {
        case 's':              /* string */
            s = va_arg(ap, char *);
            printf("string %s\n", s);
            break;
        case 'd':              /* int */
            d = va_arg(ap, int);
            printf("int %d\n", d);
            break;
        case 'c':              /* char */
            /* need a cast here since va_arg only
               takes fully promoted types */
            c = (char) va_arg(ap, int);
            printf("char %c\n", c);
            break;
        }
    va_end(ap);
}
Paul
  • 20,883
  • 7
  • 57
  • 74
-2

There is a library which includes this functionality. Here is some example code from the reference:

#include <stdarg.h>     /* va_list, va_start, va_arg, va_end */

int FindMax (int n, ...)
{
    int i,val,largest;
    va_list vl;
    va_start(vl,n);
    largest=va_arg(vl,int);
    for (i=1;i<n;i++)
    {
        val=va_arg(vl,int);
        largest=(largest>val)?largest:val;
    }
    va_end(vl);
    return largest;
}

The ellipsis is actually valid code, and you can use the va_list object to parse a variable number of parameters.

Parker Kemp
  • 719
  • 1
  • 10
  • 23
  • 2
    Thank you for answering, but I know what varargs are, and that wasn't what I asked for. – JJS Apr 05 '13 at 14:42